<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class=""><span style="color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class="">In order to be able to write extensions accross both </span><code class="" style="color: rgb(51, 51, 51); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">String</code><span style="color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class=""> and </span><code class="" style="color: rgb(51, 51, 51); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">Substring</code><span style="color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class="">, a new </span><code class="" style="color: rgb(51, 51, 51); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">Unicode</code><span style="color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class=""> protocol to which the two types will conform will be introduced. For the purposes of this proposal, </span><code class="" style="color: rgb(51, 51, 51); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">Unicode</code><span style="color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class=""> will be defined as a protocol to be used whenver you would previously extend </span><code class="" style="color: rgb(51, 51, 51); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">String</code><span style="color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class="">. It should be possible to substitute </span><code class="" style="color: rgb(51, 51, 51); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">extension Unicode { ... }</code><span style="color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class=""> in Swift 4 wherever </span><code class="" style="color: rgb(51, 51, 51); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">extension String { ... }</code><span style="color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class=""> was written in Swift 3, with one exception: any passing of </span><code class="" style="color: rgb(51, 51, 51); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">self</code><span style="color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class=""> into an API that takes a concrete </span><code class="" style="color: rgb(51, 51, 51); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">String</code><span style="color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class=""> will need to be rewritten as </span><code class="" style="color: rgb(51, 51, 51); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">String(self)</code><span style="color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class="">. If </span><code class="" style="color: rgb(51, 51, 51); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">Self</code><span style="color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class=""> is a </span><code class="" style="color: rgb(51, 51, 51); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">String</code><span style="color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class=""> then this should effectively optimize to a no-op, whereas if </span><code class="" style="color: rgb(51, 51, 51); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">Self</code><span style="color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class=""> is a </span><code class="" style="color: rgb(51, 51, 51); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">Substring</code><span style="color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class=""> then this will force a copy, helping to avoid the “memory leak” problems described above.</span></div></blockquote><div><br class=""></div><div>Did you consider an AnyUnicode<Encoding> wrapper? Then we could have a typealias called “AnyString”.</div><div><br class=""></div><div>Also, regarding naming: “Unicode” is great if this was a namespace, and this proposal is a great example of why protocol nesting is badly needed in Swift code which defines (not even very complex) protocols. However, absent protocol nesting, I think “UnicodeEncoded” is better. It doesn’t roll off the tongue as nicely, perhaps, but it also doesn’t look as weird when written in code.</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=""><p style="box-sizing: border-box; margin: 0px 0px 16px; color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class="">The exact nature of the protocol – such as which methods should be protocol requirements vs which can be implemented as protocol extensions, are considered implementation details and so not covered in this proposal.</p></div></div></div></blockquote><div>I’d hope they do get a proposal at some stage, though. There are cases where I’d like to be able to write my own “Unicode” type and take advantage of generic (and existential when we can) text processing.</div><div><br class=""></div><div>For example, maybe the thing I want to present as a single block of text is actually pieced together from multiple discontiguous regions of a buffer (i.e. the “buffer-gap” approach for faster random insertions/deletions, if I expect my code to be doing lots of that).</div><div><br class=""></div><div>You could imagine that if something like CoreText (can’t speak for them, of course) were being rewritten in Swift, it would be able to compute layouts and render glyphs from <i class="">any</i> provider of unicode data and not just String or Substring. I mean, that’s my dream, anyway. It would mean you could go directly from a buffer-gap String to a rendered bitmap suitable for UI.</div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><p style="box-sizing: border-box; margin: 0px 0px 16px; color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class=""><code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Unicode</code> will conform to <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">BidirectionalCollection</code>. <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">RangeReplaceableCollection</code> conformance will be added directly onto the <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">String</code> and <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Substring</code> types, as it is possible future <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Unicode</code>-conforming types might not be range-replaceable (e.g. an immutable type that wraps a <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">const char *</code>).</p></div></div></blockquote>+1. Keep the protocol focussed.</div><div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><p style="box-sizing: border-box; margin: 0px 0px 16px; color: rgb(51, 51, 51); font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 12.799999237060547px; background-color: rgb(255, 255, 255);" class="">The standard library currently lacks a <code class="" style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">Latin1</code> codec, so a <code class="" style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10.880000114440918px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">enum Latin1: UnicodeEncoding</code> type will be added.</p></div></div></blockquote>I feel this is a call for better naming somewhere.</div><div><br class=""></div><blockquote type="cite" class=""> init<Encoding: UnicodeEncoding>(<br class=""> cString nulTerminatedCodeUnits: UnsafePointer<Encoding.CodeUnit>,<br class=""><div><div class=""> encoding: Encoding)</div></div></blockquote><div></div><div><br class=""></div><div>So will this replace the stuff which Foundation puts in to String, which also decodes a C string in to Swift string?</div><div><br class=""></div><div>Foundation includes more encodings (and also nests an “Encoding” enum in String itself, which makes things even more confusing), but totally ignores standard library decodes in favour of CF ones.</div><br class=""><div class="">- Karl</div></body></html>