<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Thank you Michael,</div><div class=""> I did that already in this extension: (as written before) </div><div class=""><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"> </div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);"><span class="" style="font-variant-ligatures: no-common-ligatures;">extension</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">String</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;">{</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">var</span><span class="" style="font-variant-ligatures: no-common-ligatures;"> count: </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Int</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> {</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">get</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> {</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">return</span><span class="" style="font-variant-ligatures: no-common-ligatures;"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">self</span><span class="" style="font-variant-ligatures: no-common-ligatures;">.characters.count</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> }</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> }</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><br class=""></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">// properties in extensions not possible</span></div><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">// var ar = Array(self.characters) </span></div></span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; min-height: 21px;"><span class="" style="font-variant-ligatures: no-common-ligatures;"></span><br class=""></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">subscript</span><span class="" style="font-variant-ligatures: no-common-ligatures;"> (n: </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Int</span><span class="" style="font-variant-ligatures: no-common-ligatures;">) -> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">String</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> {</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">return</span><span class="" style="font-variant-ligatures: no-common-ligatures;"> String(Array(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">self</span><span class="" style="font-variant-ligatures: no-common-ligatures;">.characters)[n])</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> }</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; min-height: 21px;" class=""><span class="" style="font-variant-ligatures: no-common-ligatures;"> </span><br class="webkit-block-placeholder"></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">subscript</span><span class="" style="font-variant-ligatures: no-common-ligatures;"> (r: </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Range</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Int</span><span class="" style="font-variant-ligatures: no-common-ligatures;">>) -> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">String</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> {</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">return</span><span class="" style="font-variant-ligatures: no-common-ligatures;"> String(Array(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">self</span><span class="" style="font-variant-ligatures: no-common-ligatures;">.characters)[r])</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> }</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; min-height: 21px;" class=""><span class="" style="font-variant-ligatures: no-common-ligatures;"> </span><br class="webkit-block-placeholder"></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">subscript</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);"> (r: </span><span class="" style="font-variant-ligatures: no-common-ligatures;">ClosedRange</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);"><</span><span class="" style="font-variant-ligatures: no-common-ligatures;">Int</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);">>) -> </span><span class="" style="font-variant-ligatures: no-common-ligatures;">String</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> {</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">return</span><span class="" style="font-variant-ligatures: no-common-ligatures;"> String(Array(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">self</span><span class="" style="font-variant-ligatures: no-common-ligatures;">.characters)[r])</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"> }</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;">}</span></div></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo;"><br class=""></div><div class="">but this is not so efficient, because for each subscript invocation</div><div class="">the Character array must be built again: ( If not cached within String) </div><div class="">I assume, it must be reloaded each time because one cannot create create new</div><div class="">properties in extensions (why not?) like a Character Array as in the above comment</div><div class=""> </div><br class=""><div><blockquote type="cite" class=""><div class="">On 22 Feb 2017, at 19:43, Michael Ilseman <<a href="mailto:milseman@apple.com" class="">milseman@apple.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; -webkit-line-break: after-white-space;" class="">Given that the behavior you desire is literally a few key strokes away (see below), it would be unfortunate to pessimize the internal representation of Strings for every application. This would destroy the applicability of the Swift standard library to entire areas of computing such as application development for mobile devices (Swift's current largest niche). The idea of abstraction is that you can provide a high-level view of things stored at a lower-level in accordance with sensible higher-level semantics and expectations. If you want random access, then you can eagerly project the characters (see below). This is consistent with the standard library’s preference for lazy sequences when providing a eager one would result in a large up-front cost that might be avoidable otherwise.<div class=""><br class=""></div></div></div></blockquote>mostly true.<br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Here’s playground code that gives you what you’re requesting, by doing an eager projection (rather than a lazy one, which is the default):</div><div class=""><br class=""></div></div></div></blockquote>Your extension is more efficient than my subscript extension above, </div><div>because the Character array is drawn once from the String, instead of that each</div><div>time the str.characters property is scanned again</div><div>@Dave :</div><div> is that the case, or is the character view cached , so that it</div><div>doesn’t matter much if the characterView is retrieved frequently? </div><div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">extension</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> characterArray: [</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Character</span><span style="font-variant-ligatures: no-common-ligatures" class="">] {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">characters</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3e1e81" class="">map</span><span style="font-variant-ligatures: no-common-ligatures" class=""> { $0</span><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> str = </span><span style="font-variant-ligatures: no-common-ligatures; color: #d12f1b" class="">"abcdefg</span><span style="font-variant-ligatures: no-common-ligatures;" class="">\</span><span style="font-variant-ligatures: no-common-ligatures; color: #d12f1b" class="">(</span><span style="font-variant-ligatures: no-common-ligatures" class="">UnicodeScalar</span><span style="font-variant-ligatures: no-common-ligatures;" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">0x302</span><span style="font-variant-ligatures: no-common-ligatures;" class="">)!</span><span style="font-variant-ligatures: no-common-ligatures; color: #d12f1b" class="">)"</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> charArray = </span><span style="font-variant-ligatures: no-common-ligatures" class="">str</span><span style="font-variant-ligatures: no-common-ligatures;" class="">.</span><span style="font-variant-ligatures: no-common-ligatures" class="">characterArray</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">charArray</span><span style="font-variant-ligatures: no-common-ligatures;" class="">[</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">4</span><span style="font-variant-ligatures: no-common-ligatures;" class="">] </span><span style="font-variant-ligatures: no-common-ligatures" class="">// results in "e"</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">charArray</span><span style="font-variant-ligatures: no-common-ligatures;" class="">[</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">6</span><span style="font-variant-ligatures: no-common-ligatures;" class="">] </span><span style="font-variant-ligatures: no-common-ligatures" class="">// results in “ĝ”</span></div></span></div></div></div></div></blockquote><div><br class=""></div>I would normally subclass String, but in Swift I can’t do this</div><div>because String is a struct, inheritance of structs is not</div><div>possible in Swift. <br class=""><div><br class=""></div>@Dave:</div><div>Thanks for the explanation and the link (it’s been a long time</div><div>ago reading about pointers, normally I try to avoid these things like the plague..) </div><div><br class=""></div><div>Factor 8? that's a big storage difference.. Currently still diving into Swift stdlib, </div><div>maybe I’ll get some bright ideas there , but don’t count on it :o) </div><div><br class=""></div><div>However, for the String struct, I have another suggestion/solution/question if I may: </div><div><br class=""></div><div>If String’s CharacterView is not cached (or is it?) to prevent repetitive regeneration,</div><div>but even then: </div><div><br class=""></div><div>What about having a (lazy) Array<Character> property inside String?</div><div>which: </div><div> is normally nil and only created when parts of aString are</div><div> accessed/changed e.g. with subscription.</div><div> will be nil again when String has changed. </div><div>can also be disposed of (to nil or emptied) upon request: </div><div> str.disposeCharacterArray() </div><div> or maybe:</div><div> str.compactString() </div><div> str.freeSpace() </div><div><br class=""></div><div>Although then available as a property like this:</div><div> str.characterArray , </div><div>normally one would not access this character array directly,</div><div>but rather implicitly with subscripting on the String itself, like str[n…m]. </div><div>In that case, if it does not already exist, this character array inside String </div><div>will be created and remains alive until aString disappears , changes, or </div><div>the string’s character array is explicitly disposed.</div><div>(e.g. useful when many strings are involved, to free storage) </div><div><br class=""></div><div>in that way:</div><div>No unnecessary storage is allocated for Character arrays, </div><div>but only when the need arises. </div><div>There are no longer performance based restrictions for the programmer</div><div>to subscript strings directly. Hooray! </div><div><br class=""></div><div>Not only to *get* but also to *set* substrings. </div><div>(The latter would of course require String-inside </div><div>processing of the Character array. updating the</div><div>in the String)</div><div><br class=""></div><div>Furthermore, one could base nearly all</div><div>string handling like substring, replace, search, etc.</div><div>directly on this character array without the </div><div>need to walk through the contiguous String storage</div><div>itself each time at runtime. </div><div><br class=""></div><div> </div><div>Flexible! So one can do all this and more: </div><div> str[5] = “x”</div><div> let s = str[5] </div><div> str[3…5] = “HAL” </div><div> str[range] = str[range].reversed() </div><div> var s = str[10..<28]</div><div> if str[p1..<p1+ length] == “Dakota” {…}</div><div> notes[bar1..<bar1+6] = “EADGBE” </div><div> etc. </div><div><br class=""></div><div> (try to do this with the existing string handling functions..)</div><div> and also roll your own string handling functions directly</div><div> based on subscripting. possibly in own extensions.</div><div>? </div><div><br class=""></div><div>In that way we can forget the imho -sorry, excuse l’moi- awkward and tedious constructions like: </div><div><span class="Apple-tab-span" style="white-space:pre">        </span><font face="Menlo" style="font-size: 12px;" color="#ff2600" class="">str.substringWithRange(Range<String.Index>(start: str.startIndex, end: str.endIndex))</font></div><div>horrible, too much typing, can’t read these things, have to look them up each time..</div><div>? </div><div>Kind Regards</div><div>TedvG</div><div>( I am Dutch and living in Germany (like being here but it doesn’t help my English much :o) )</div><div><a href="http://www.tedvg.com" class="">www.tedvg.com</a></div><div><a href="http://www.ravelnotes.com" class="">www.ravelnotes.com</a></div><div> </div><div> </div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class="">Note that you get random access AND safety by operating at the Character level. If you operate at the unicode scalar value level instead, you might be splitting canonical combining sequences accidentally.</span></div></span></div><div class=""><br class=""></div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Feb 22, 2017, at 7:56 AM, Ted F.A. van Gaalen via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@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; -webkit-line-break: after-white-space;" class="">Hi Ben,<div class="">thank you, yes, I know all that by now. </div><div class=""><br class=""></div><div class="">Have seen that one goes to great lengths to optimise, not only for storage but also for speed. But how far does this need to go? In any case, optimisation should not be used</div><div class="">as an argument for restricting a PLs functionality that is to refrain from PL elements which are common and useful.?</div><div class=""><br class=""></div><div class="">I wouldn’t worry so much over storage (unless one wants to load a complete book into memory… in iOS, the average app is about 15-50 MB, String data is mostly a fraction of that. In macOS or similar I’d think it is even less significant…</div><div class=""><br class=""></div><div class="">I wonder how much performance and memory consumption would be different from the current contiguous memory implementation? if a String is just is a plain row of (references to) Character (extended grapheme cluster) objects, Array<[Character>, which would simplify the basic logic and (sub)string handling significantly, because then one has direct access to the String’s elements directly, using the reasonably fast access methods of a Swift Collection/Array. </div><div class=""><br class=""></div><div class="">I have experimented with an alternative String struct based upon Array<Character>, seeing how easy it was to implement most popular string handling functions as one can work with the Character array directly. </div><div class=""><br class=""></div><div class="">Currently at deep-dive-depth in the standard lib sources, especially String & Co.</div><div class=""><br class=""></div><div class="">Kind Regards</div><div class="">TedvG</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class=""><blockquote type="cite" class=""><div class="">On 21 Feb 2017, at 01:31, Ben Cohen <<a href="mailto:ben_cohen@apple.com" class="">ben_cohen@apple.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; -webkit-line-break: after-white-space;" class="">Hi Ted,<div class=""><br class=""></div><div class="">While Character is the Element type for String, it would be unsuitable for a String’s implementation to actually use Character for storage. Character is fairly large (currently 9 bytes), very little of which is used for most values. For unusual graphemes that require more storage, it allocates more memory on the heap. By contrast, String’s actual storage is a buffer of 1- or 2-byte elements, and all graphemes (what we expose as Characters) are held in that contiguous memory no matter how many code points they comprise. When you iterate over the string, the graphemes are unpacked into a Character on the fly. This gives you an user interface of a collection that superficially appears to resemble [Character], but this does not mean that this would be a workable implementation.</div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Feb 20, 2017, at 12:59 PM, Ted F.A. van Gaalen <<a href="mailto:tedvgiosdev@gmail.com" class="">tedvgiosdev@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Ben, Dave (you should not read this now, you’re on vacation :o) & Others<div class=""><br class=""></div><div class="">As described in the Swift Standard Library API Reference:</div><div class=""><br class=""></div><div class=""><div style="box-sizing: inherit; margin: 0px; padding: 0px; color: rgb(51, 51, 51); font-family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', Helvetica, Arial, sans-serif; letter-spacing: -0.3569999933242798px;" class="">The <code class="code-voice" style="box-sizing: inherit; font-family: 'SF Mono', Menlo, monospace;">Character</code> type represents a character made up of one or more Unicode scalar values, </div><div style="box-sizing: inherit; margin: 0px; padding: 0px; color: rgb(51, 51, 51); font-family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', Helvetica, Arial, sans-serif; letter-spacing: -0.3569999933242798px;" class="">grouped by a Unicode boundary algorithm. Generally, a <code class="code-voice" style="box-sizing: inherit; font-family: 'SF Mono', Menlo, monospace;">Character</code> instance matches what </div><div style="box-sizing: inherit; margin: 0px; padding: 0px; color: rgb(51, 51, 51); font-family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', Helvetica, Arial, sans-serif; letter-spacing: -0.3569999933242798px;" class="">the reader of a string will perceive as a single character. The number of visible characters is </div><div style="box-sizing: inherit; margin: 0px; padding: 0px; color: rgb(51, 51, 51); font-family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', Helvetica, Arial, sans-serif; letter-spacing: -0.3569999933242798px;" class="">generally the most natural way to count the length of a string.</div><figure id="2844880" style="box-sizing: inherit; margin: -62px 0px 0px; padding: 1.4em 0px 0px; border-top-width: 62px; border-top-style: solid; border-top-color: transparent; position: static; color: rgb(51, 51, 51); font-family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', Helvetica, Arial, sans-serif; letter-spacing: -0.3569999933242798px;" class=""><div class="formatted-content" style="box-sizing: inherit;"></div></figure></div><div class=""><div class="">The smallest discrete unit we (app programmers) are mostly working with is this</div><div class="">perceived visible character, what else? </div><div class=""><br class=""></div></div><div class="">If that is the case, my reasoning is, that Strings (could / should? ) be relatively simple, </div><div class="">because most, if not all, complexity of Unicode is confined within the Character object and</div><div class="">completely hidden** for the average application programmer, who normally only needs</div><div class="">to work with Strings which contains these visible Characters, right? </div><div class="">It doesn’t then make no difference at all “what’ is in” the Character, (excellent implementation btw) </div><div class="">(Unicode, ASCCII, EBCDIC, Elvish, KlingonIV, IntergalacticV.2, whatever)</div><div class="">because we rely in sublime oblivion for the visually representation of whatever is in</div><div class="">the Character on miraculous font processors hidden in the dark depths of the OS. </div><div class=""><br class=""></div><div class="">Then, in this perspective, my question is: why is String not implemented as </div><div class="">directly based upon an array [Character] ? In that case one can refer to the Characters of the</div><div class="">String directly, not only for direct subscripting and other String functionality in an efficient way. </div><div class="">(i do hava scope of independent Swift here, that is interaction with libraries should be </div><div class="">solved by the compiler, so as not to be restricted by legacy ObjC etc. </div><div class=""><br class=""></div><div class="">** (expect if one needs to do e.g. access individual elements and/or compose graphics directly?</div><div class=""> but for this purpose the Character’s properties are accessible) </div><div class=""><br class=""></div><div class="">For the sake of convenience, based upon the above reasoning, I now “emulate" this in </div><div class="">a string extension, thereby ignoring the rare cases that a visible character could be based </div><div class="">upon more than a single Character (extended grapheme cluster) If that would occur, </div><div class="">thye should be merged into one extended grapheme cluster, a single Character that is. </div><div class=""><br class=""></div><div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">//: Playground - implement direct subscripting using a Character array</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">// of course, when the String is defined as an array of Characters, directly</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">// accessible it would be more efficient as in these extension functions. </span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">extension</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">{</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> count: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">get</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.characters.count</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; min-height: 21px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">subscript</span><span style="font-variant-ligatures: no-common-ligatures" class=""> (n: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span><span style="font-variant-ligatures: no-common-ligatures" class="">) -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> String(Array(</span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.characters)[n])</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; min-height: 21px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><br class="webkit-block-placeholder"></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">subscript</span><span style="font-variant-ligatures: no-common-ligatures" class=""> (r: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Range</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span><span style="font-variant-ligatures: no-common-ligatures" class="">>) -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> String(Array(</span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.characters)[r])</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; min-height: 21px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><br class="webkit-block-placeholder"></div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">subscript</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> (r: </span><span style="font-variant-ligatures: no-common-ligatures" class="">ClosedRange</span><span style="font-variant-ligatures: no-common-ligatures;" class=""><</span><span style="font-variant-ligatures: no-common-ligatures" class="">Int</span><span style="font-variant-ligatures: no-common-ligatures;" class="">>) -> </span><span style="font-variant-ligatures: no-common-ligatures" class="">String</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> String(Array(</span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.characters)[r])</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; min-height: 21px;" class=""><br class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> test()</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">{</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> zoo = </span><span style="font-variant-ligatures: no-common-ligatures" class="">"Koala </span><span style="line-height: normal; font-family: 'Apple Color Emoji'; font-variant-ligatures: no-common-ligatures;" class="">🐨</span><span style="font-variant-ligatures: no-common-ligatures" class="">, Snail </span><span style="line-height: normal; font-family: 'Apple Color Emoji'; font-variant-ligatures: no-common-ligatures;" class="">🐌</span><span style="font-variant-ligatures: no-common-ligatures" class="">, Penguin </span><span style="line-height: normal; font-family: 'Apple Color Emoji'; font-variant-ligatures: no-common-ligatures;" class="">🐧</span><span style="font-variant-ligatures: no-common-ligatures" class="">, Dromedary </span><span style="line-height: normal; font-family: 'Apple Color Emoji'; font-variant-ligatures: no-common-ligatures;" class="">🐪</span><span style="font-variant-ligatures: no-common-ligatures" class="">"</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""> print(</span><span style="font-variant-ligatures: no-common-ligatures" class="">"zoo has </span><span style="font-variant-ligatures: no-common-ligatures;" class="">\</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures;" class="">zoo.count</span><span style="font-variant-ligatures: no-common-ligatures" class="">) characters (discrete extended graphemes):"</span><span style="font-variant-ligatures: no-common-ligatures;" class="">)</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">for</span><span style="font-variant-ligatures: no-common-ligatures" class=""> i </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">in</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">0</span><span style="font-variant-ligatures: no-common-ligatures" class="">..<zoo.count</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> print(i,zoo[i],separator: </span><span style="font-variant-ligatures: no-common-ligatures; color: #d12f1b" class="">"="</span><span style="font-variant-ligatures: no-common-ligatures" class="">, terminator:</span><span style="font-variant-ligatures: no-common-ligatures; color: #d12f1b" class="">" "</span><span style="font-variant-ligatures: no-common-ligatures" class="">)</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> print(</span><span style="font-variant-ligatures: no-common-ligatures; color: #d12f1b" class="">"\n"</span><span style="font-variant-ligatures: no-common-ligatures" class="">)</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> print(zoo[</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">0</span><span style="font-variant-ligatures: no-common-ligatures" class="">..<</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">7</span><span style="font-variant-ligatures: no-common-ligatures" class="">])</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> print(zoo[</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">9</span><span style="font-variant-ligatures: no-common-ligatures" class="">..<</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">16</span><span style="font-variant-ligatures: no-common-ligatures" class="">])</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> print(zoo[</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">18</span><span style="font-variant-ligatures: no-common-ligatures" class="">...</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">26</span><span style="font-variant-ligatures: no-common-ligatures" class="">])</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> print(zoo[</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">29</span><span style="font-variant-ligatures: no-common-ligatures" class="">...</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">39</span><span style="font-variant-ligatures: no-common-ligatures" class="">])</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> print(</span><span style="font-variant-ligatures: no-common-ligatures; color: #d12f1b" class="">"images:"</span><span style="font-variant-ligatures: no-common-ligatures" class=""> + zoo[</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">6</span><span style="font-variant-ligatures: no-common-ligatures" class="">] + zoo[</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">15</span><span style="font-variant-ligatures: no-common-ligatures" class="">] + zoo[</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">26</span><span style="font-variant-ligatures: no-common-ligatures" class="">] + zoo[</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">39</span><span style="font-variant-ligatures: no-common-ligatures" class="">])</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; min-height: 21px;" class=""><br class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">test()</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; min-height: 21px;" class=""><br class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span></div></div><div class="">this works as intended and generates the following output: </div><div class=""><br class=""></div><div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">zoo has 40 characters (discrete extended graphemes):</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">0=K 1=o 2=a 3=l 4=a 5= 6=</span><span style="line-height: normal; font-family: 'Apple Color Emoji'; font-variant-ligatures: no-common-ligatures;" class="">🐨</span><span style="font-variant-ligatures: no-common-ligatures" class=""> 7=, 8= 9=S 10=n 11=a 12=i 13=l 14= 15=</span><span style="line-height: normal; font-family: 'Apple Color Emoji'; font-variant-ligatures: no-common-ligatures;" class="">🐌</span><span style="font-variant-ligatures: no-common-ligatures" class=""> 16=, 17= </span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">18=P 19=e 20=n 21=g 22=u 23=i 24=n 25= 26=</span><span style="line-height: normal; font-family: 'Apple Color Emoji'; font-variant-ligatures: no-common-ligatures;" class="">🐧</span><span style="font-variant-ligatures: no-common-ligatures" class=""> 27=, 28= 29=D 30=r 31=o 32=m </span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">33=e 34=d 35=a 36=r 37=y 38= 39=</span><span style="line-height: normal; font-family: 'Apple Color Emoji'; font-variant-ligatures: no-common-ligatures;" class="">🐪</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; min-height: 21px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">Koala </span><span style="line-height: normal; font-family: 'Apple Color Emoji'; font-variant-ligatures: no-common-ligatures;" class="">🐨</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">Snail </span><span style="line-height: normal; font-family: 'Apple Color Emoji'; font-variant-ligatures: no-common-ligatures;" class="">🐌</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">Penguin </span><span style="line-height: normal; font-family: 'Apple Color Emoji'; font-variant-ligatures: no-common-ligatures;" class="">🐧</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">Dromedary </span><span style="line-height: normal; font-family: 'Apple Color Emoji'; font-variant-ligatures: no-common-ligatures;" class="">🐪</span></div><div style="margin: 0px; line-height: normal; font-family: 'Apple Color Emoji';" class=""><span style="line-height: normal; font-family: Menlo; font-variant-ligatures: no-common-ligatures;" class="">images:</span><span style="font-variant-ligatures: no-common-ligatures" class="">🐨🐌🐧🐪</span></div></div><div class=""><br class=""></div><div class="">I don’t know how (in) efficient this method is. </div><div class=""><div class="">but in many cases this is not so important as e.g. with numerical computation.</div></div><div class=""><br class=""></div><div class="">I still fail to understand why direct subscripting strings would be unnecessary,</div><div class="">and would like to see this built-in in Swift asap. </div><div class=""><br class=""></div><div class="">Btw, I do share the concern as expressed by Rien regarding the increasing complexity of the language.</div><div class=""><br class=""></div><div class="">Kind Regards, </div><div class=""><br class=""></div><div class="">TedvG</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""> </div></div></div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div></div></div></blockquote></div><br class=""></body></html>