<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div style="font-family:Arial;">Loving it so far.<br></div>
<div style="font-family:Arial;"><br></div>
<div style="font-family:Arial;">`encode` and `parseScalar[Forward|Backward]` feel asymmetric. What's wrong with `decode[Forward|Backward]`?<br></div>
<div style="font-family:Arial;"><br></div>
<div style="font-family:Arial;">`UnicodeParseResult&lt;T, Index&gt;` really feels like it could/should be defined as `UnicodeEncoding.ParseResult&lt;Index&gt;` (or `DecodeResult`, given the above).&nbsp;I can't remember if that generics limitation was being lifted?<br></div>
<div style="font-family:Arial;"><br></div>
<div id="sig40804545"><div class="signature"><span class="font" style="font-family:arial, sans-serif, sans-serif">Best,</span><span class="font" style="font-family:arial, sans-serif, sans-serif"></span><br></div>
<div class="signature"><span class="font" style="font-family:arial, sans-serif, sans-serif">&nbsp; Zachary Waldowski</span><span class="font" style="font-family:arial, sans-serif, sans-serif"></span><br></div>
<div class="signature"><span class="font" style="font-family:arial, sans-serif, sans-serif">&nbsp;&nbsp;</span><a href="mailto:zach@waldowski.me"><span class="font" style="font-family:arial, sans-serif, sans-serif">zach@waldowski.me</span></a><br></div>
</div>
<div><br></div>
<div><br></div>
<div>On Wed, Mar 29, 2017, at 08:32 PM, Ben Cohen via swift-evolution wrote:<br></div>
<blockquote type="cite"><div style="font-family:Arial;">Hi Swift Evolution,<br></div>
<div><br></div>
<div>Below is a pitch for the first part of the String revision. This covers a number of changes that would allow the basic internals to be overhauled.<br></div>
<div><br></div>
<div>Online version here:&nbsp;<a href="https://github.com/airspeedswift/swift-evolution/blob/3a822c799011ace682712532cfabfe32e9203fbb/proposals/0161-StringRevision1.md">https://github.com/airspeedswift/swift-evolution/blob/3a822c799011ace682712532cfabfe32e9203fbb/proposals/0161-StringRevision1.md</a><br></div>
<div><br></div>
<div><br></div>
<div><h1 style="font-size:2.25em;margin-right:0px;margin-bottom:16px;margin-left:0px;line-height:1.2;position:relative;color:rgb(51, 51, 51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238, 238, 238);font-family:helvetica, arial, freesans, clean, sans-serif;background-color:rgb(255, 255, 255);margin-top:0px !important;">String Revision: Collection Conformance, C Interop, Transcoding<br></h1><ul style="padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:2em;margin-top:0px;margin-bottom:16px;color:rgb(51, 51, 51);font-family:helvetica, arial, freesans, clean, sans-serif;font-size:12.799999237060547px;background-color:rgb(255, 255, 255);"><li style="">Proposal:&nbsp;<a style="background-color:transparent;color:rgb(65, 131, 196);text-decoration:none;">SE-0161</a><br></li><li style="">Authors:&nbsp;<a href="https://github.com/airspeedswift" style="background-color:transparent;color:rgb(65, 131, 196);text-decoration:none;">Ben Cohen</a>,&nbsp;<a href="http://github.com/dabrahams/" style="background-color:transparent;color:rgb(65, 131, 196);text-decoration:none;">Dave Abrahams</a><br></li><li style="">Review Manager: TBD<br></li><li style="">Status:&nbsp;<b>Awaiting review</b><br></li></ul><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;position:relative;color:rgb(51, 51, 51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238, 238, 238);font-family:helvetica, arial, freesans, clean, sans-serif;background-color:rgb(255, 255, 255);">Introduction<br></h2><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">This proposal is to implement a subset of the changes from the&nbsp;<a href="https://github.com/apple/swift/blob/master/docs/StringManifesto.md" style="background-color:transparent;color:rgb(65, 131, 196);text-decoration:none;">Swift 4 String Manifesto</a>.</span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">Specifically:</span></span></span></span><br></p><ul style="padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:2em;margin-top:0px;margin-bottom:16px;color:rgb(51, 51, 51);font-family:helvetica, arial, freesans, clean, sans-serif;font-size:12.799999237060547px;background-color:rgb(255, 255, 255);"><li style="">Make&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;conform to&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">BidirectionalCollection</code><br></li><li style="">Make&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;conform to&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">RangeReplaceableCollection</code><br></li><li style="">Create a&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;type for&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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.SubSequence</code><br></li><li style="">Create a&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;protocol to allow for generic operations over both types.<br></li><li style="">Consolidate on a concise set of C interop methods.<br></li><li style=""><u></u>Revise the transcoding infrastructure.<br></li></ul><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">Other existing aspects of&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;remain unchanged for the purposes of this proposal.</span></span></span></span><br></p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;position:relative;color:rgb(51, 51, 51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238, 238, 238);font-family:helvetica, arial, freesans, clean, sans-serif;background-color:rgb(255, 255, 255);">Motivation<br></h2><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">This proposal follows up on a number of recommendations found in the manifesto:</span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px"><code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">Collection</code>&nbsp;conformance was dropped from&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;in Swift 2. After reevaluation, the feeling is that the minor semantic discrepancies (mainly with&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">RangeReplaceableCollection</code>) are outweighed by the significant benefits of restoring these conformances. For more detail on the reasoning, see&nbsp;<a href="https://github.com/apple/swift/blob/master/docs/StringManifesto.md#string-should-be-a-collection-of-characters-again" style="background-color:transparent;color:rgb(65, 131, 196);text-decoration:none;">here</a></span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">While it is not a collection, the Swift 3 string does have slicing operations.&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;is currently serving as its own subsequence, allowing substrings to share storage with their “owner”. This can lead to memory leaks when small substrings of larger strings are stored long-term (see&nbsp;<a href="https://github.com/apple/swift/blob/master/docs/StringManifesto.md#substrings" style="background-color:transparent;color:rgb(65, 131, 196);text-decoration:none;">here</a>&nbsp;for more detail on this problem). Introducing a separate type of&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;to serve as&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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.Subsequence</code>&nbsp;is recommended to resolve this issue, in a similar fashion to&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">ArraySlice</code>.</span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">As noted in the manifesto, support for interoperation with nul-terminated C strings in Swift 3 is scattered and incoherent, with 6 ways to transform a C string into a&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;and four ways to do the inverse. These APIs should be replaced with a simpler set of methods on&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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></span></span></span><br></p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;position:relative;color:rgb(51, 51, 51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238, 238, 238);font-family:helvetica, arial, freesans, clean, sans-serif;background-color:rgb(255, 255, 255);">Proposed solution<br></h2><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">A new type,&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>, will be introduced. Similar to&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">ArraySlice</code>&nbsp;it will be documented as only for short- to medium-term storage:</span></span></span></span><br></p><blockquote style="margin-top:0px;margin-right:0px;margin-bottom:16px;margin-left:0px;padding-top:0px;padding-right:15px;padding-bottom:0px;padding-left:15px;color:rgb(119, 119, 119);border-left-width:4px;border-left-style:solid;border-left-color:rgb(221, 221, 221);font-family:helvetica, arial, freesans, clean, sans-serif;font-size:12.799999237060547px;background-color:rgb(255, 255, 255);"><p style="margin-top:0px;margin-right:0px;margin-bottom:16px;margin-left:0px;"><b>Important</b><br></p><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;">Long-term storage of&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;instances is discouraged. A substring holds a reference to the entire storage of a larger string, not just to the portion it presents, even after the original string’s lifetime ends. Long-term storage of a substring may therefore prolong the lifetime of elements that are no longer otherwise accessible, which can appear to be memory leakage.<br></div>
</blockquote><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">Aside from minor differences, such as having a&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">SubSequence</code>&nbsp;of&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;and a larger size to describe the range of the subsequence,&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;will be near-identical from a user perspective.</span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">In order to be able to write extensions accross both&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;and&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>, a new&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;protocol to which the two types will conform will be introduced. For the purposes of this proposal,&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;will be defined as a protocol to be used whenver you would previously extend&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>. It should be possible to substitute&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;in Swift 4 wherever&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;was written in Swift 3, with one exception: any passing of&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;into an API that takes a concrete&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;will need to be rewritten as&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>. If&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;is a&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;then this should effectively optimize to a no-op, whereas if&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;is a&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;then this will force a copy, helping to avoid the “memory leak” problems described above.</span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">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.</span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px"><code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;will conform to&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">BidirectionalCollection</code>.&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">RangeReplaceableCollection</code>&nbsp;conformance will be added directly onto the&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;and&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;types, as it is possible future&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>-conforming types might not be range-replaceable (e.g. an immutable type that wraps a&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">const char *</code>).</span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">The C string interop methods will be updated to those described&nbsp;<a href="https://github.com/apple/swift/blob/master/docs/StringManifesto.md#c-string-interop" style="background-color:transparent;color:rgb(65, 131, 196);text-decoration:none;">here</a>: a single&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">withCString</code>&nbsp;operation and two&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">init(cString:)</code>&nbsp;constructors, one for UTF8 and one for arbitrary encodings. The primary change is to remove “non-repairing” variants of construction from nul-terminated C strings. In both of the construction APIs, any invalid encoding sequence detected will have its longest valid prefix replaced by&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">U+FFFD</code>, the Unicode replacement character, per the Unicode specification. This covers the common case. The replacement is done physically in the underlying storage and the validity of the result is recorded in the String’s encoding such that future accesses need not be slowed down by possible error repair separately. Construction that is aborted when encoding errors are detected can be accomplished using APIs on the encoding.</span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">The current transcoding support will be updated to improve usability and performance. The primary changes will be:</span></span></span></span><br></p><ul style="padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:2em;margin-top:0px;margin-bottom:16px;color:rgb(51, 51, 51);font-family:helvetica, arial, freesans, clean, sans-serif;font-size:12.799999237060547px;background-color:rgb(255, 255, 255);"><li style="">to allow transcoding directly from one encoding to another without having to triangulate through an intermediate scalar value<br></li><li style="">to add the ability to transcode an input collection in reverse, allowing the different views on&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;to be made bi-directional<br></li><li style="">to have decoding take a collection rather than an iterator, and return an index of its progress into the source, allowing that method to be static<br></li></ul><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">The standard library currently lacks a&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;codec, so a&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;type will be added.</span></span></span></span><br></p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;position:relative;color:rgb(51, 51, 51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238, 238, 238);font-family:helvetica, arial, freesans, clean, sans-serif;background-color:rgb(255, 255, 255);">Detailed design<br></h2><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">The following additions will be made to the standard library:</span></span></span></span><br></p><pre style="overflow-x:auto;overflow-y:auto;font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;margin-top:0px;margin-bottom:16px;font-stretch:normal;line-height:1.45;padding-top:16px;padding-right:16px;padding-bottom:16px;padding-left:16px;background-color:rgb(248, 248, 248);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal;color:rgb(51, 51, 51);height:248px;"><code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;padding-top:0.5em;padding-right:0.5em;padding-bottom:0.5em;padding-left:0.5em;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-top-style:initial;border-right-style:initial;border-bottom-style:initial;border-left-style:initial;border-top-color:initial;border-right-color:initial;border-bottom-color:initial;border-left-color:initial;border-image-source:initial;border-image-slice:initial;border-image-width:initial;border-image-outset:initial;border-image-repeat:initial;display:block;overflow-x:auto;line-height:inherit;word-wrap:normal;height:auto;"><span style=""><b>protocol</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>Unicode</b></span>: <span class="colour" style="color:rgb(68, 85, 136)"><b>BidirectionalCollection</b></span> </span>{
  <span class="colour" style="color:rgb(153, 153, 136)"><i>// Implementation detail as described above</i></span>
}

<span style=""><b>extension</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>String</b></span>: <span class="colour" style="color:rgb(68, 85, 136)"><b>Unicode</b></span>, <span class="colour" style="color:rgb(68, 85, 136)"><b>RangeReplaceableCollection</b></span> </span>{
  <b>typealias</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>SubSequence</b></span> = <span class="colour" style="color:rgb(68, 85, 136)"><b>Substring</b></span>
}

<span style=""><b>struct</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>Substring</b></span>: <span class="colour" style="color:rgb(68, 85, 136)"><b>Unicode</b></span>, <span class="colour" style="color:rgb(68, 85, 136)"><b>RangeReplaceableCollection</b></span> </span>{
  <b>typealias</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>SubSequence</b></span> = <span class="colour" style="color:rgb(68, 85, 136)"><b>Substring</b></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>// near-identical API surface area to String</i></span>
}</code><br></pre><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">The subscript operations on&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;will be amended to return&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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></span></span></span><br></p><pre style="overflow-x:auto;overflow-y:auto;font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;margin-top:0px;margin-bottom:16px;font-stretch:normal;line-height:1.45;padding-top:16px;padding-right:16px;padding-bottom:16px;padding-left:16px;background-color:rgb(248, 248, 248);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal;color:rgb(51, 51, 51);height:112px;"><code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;padding-top:0.5em;padding-right:0.5em;padding-bottom:0.5em;padding-left:0.5em;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-top-style:initial;border-right-style:initial;border-bottom-style:initial;border-left-style:initial;border-top-color:initial;border-right-color:initial;border-bottom-color:initial;border-left-color:initial;border-image-source:initial;border-image-slice:initial;border-image-width:initial;border-image-outset:initial;border-image-repeat:initial;display:block;overflow-x:auto;line-height:inherit;word-wrap:normal;height:auto;"><span style=""><b>struct</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>String</b></span> </span>{
  <b>subscript</b>(bounds: <span class="colour" style="color:rgb(68, 85, 136)"><b>Range</b></span>&lt;<span class="colour" style="color:rgb(68, 85, 136)"><b>String</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Index</b></span>&gt;) -&gt; <span class="colour" style="color:rgb(68, 85, 136)"><b>Substring</b></span> { <b>get</b> }
  <b>subscript</b>(bounds: <span class="colour" style="color:rgb(68, 85, 136)"><b>ClosedRange</b></span>&lt;<span class="colour" style="color:rgb(68, 85, 136)"><b>String</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Index</b></span>&gt;) -&gt; <span class="colour" style="color:rgb(68, 85, 136)"><b>Substring</b></span> { <b>get</b> }
}</code><br></pre><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">Note that properties or methods that due to their nature create new&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;storage (such as&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">lowercased()</code>) will&nbsp;<i>not</i>&nbsp;change.</span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">C string interop will be consolidated on the following methods:</span></span></span></span><br></p><pre style="overflow-x:auto;overflow-y:auto;font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;margin-top:0px;margin-bottom:16px;font-stretch:normal;line-height:1.45;padding-top:16px;padding-right:16px;padding-bottom:16px;padding-left:16px;background-color:rgb(248, 248, 248);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal;color:rgb(51, 51, 51);height:418px;"><code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;padding-top:0.5em;padding-right:0.5em;padding-bottom:0.5em;padding-left:0.5em;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-top-style:initial;border-right-style:initial;border-bottom-style:initial;border-left-style:initial;border-top-color:initial;border-right-color:initial;border-bottom-color:initial;border-left-color:initial;border-image-source:initial;border-image-slice:initial;border-image-width:initial;border-image-outset:initial;border-image-repeat:initial;display:block;overflow-x:auto;line-height:inherit;word-wrap:normal;height:auto;"><span style=""><b>extension</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>String</b></span> </span>{
  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// Constructs a `String` having the same contents as `nulTerminatedUTF8`.</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>///</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// - Parameter nulTerminatedUTF8: a sequence of contiguous UTF-8 encoded </i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>///   bytes ending just before the first zero byte (NUL character).</i></span>
  <b>init</b>(cString nulTerminatedUTF8: <span class="colour" style="color:rgb(68, 85, 136)"><b>UnsafePointer</b></span>&lt;<span class="colour" style="color:rgb(68, 85, 136)"><b>CChar</b></span>&gt;)
  
  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// Constructs a `String` having the same contents as `nulTerminatedCodeUnits`.</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>///</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// - Parameter nulTerminatedCodeUnits: a sequence of contiguous code units in</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>///   the given `encoding`, ending just before the first zero code unit.</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// - Parameter encoding: describes the encoding in which the code units</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>///   should be interpreted.</i></span>
  <b>init</b>&lt;<span class="colour" style="color:rgb(68, 85, 136)"><b>Encoding</b></span>: <span class="colour" style="color:rgb(68, 85, 136)"><b>UnicodeEncoding</b></span>&gt;(
    cString nulTerminatedCodeUnits: <span class="colour" style="color:rgb(68, 85, 136)"><b>UnsafePointer</b></span>&lt;<span class="colour" style="color:rgb(68, 85, 136)"><b>Encoding</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>CodeUnit</b></span>&gt;,
    encoding: <span class="colour" style="color:rgb(68, 85, 136)"><b>Encoding</b></span>)
    
  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// Invokes the given closure on the contents of the string, represented as a</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// pointer to a null-terminated sequence of UTF-8 code units.</i></span>
  <span style=""><b>func</b> <span class="colour" style="color:rgb(153, 0, 0)"><b>withCString</b></span>&lt;Result&gt;<span style="">(
    <span class="colour" style="color:rgb(0, 128, 128)">_</span> body: <span style="">(UnsafePointer&lt;CChar&gt;)</span></span></span> <b>throws</b> -&gt; <span class="colour" style="color:rgb(68, 85, 136)"><b>Result</b></span>) <b>rethrows</b> -&gt; <span class="colour" style="color:rgb(68, 85, 136)"><b>Result</b></span>
}</code><br></pre><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">Additionally, the current ability to pass a Swift&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;into C methods that take a C string will remain as-is.</span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">A new protocol,&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">UnicodeEncoding</code>, will be added to replace the current&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">UnicodeCodec</code>&nbsp;protocol:</span></span></span></span><br></p><pre style="overflow-x:auto;overflow-y:auto;font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;margin-top:0px;margin-bottom:16px;font-stretch:normal;line-height:1.45;padding-top:16px;padding-right:16px;padding-bottom:16px;padding-left:16px;background-color:rgb(248, 248, 248);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal;color:rgb(51, 51, 51);height:1353px;"><code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;padding-top:0.5em;padding-right:0.5em;padding-bottom:0.5em;padding-left:0.5em;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-top-style:initial;border-right-style:initial;border-bottom-style:initial;border-left-style:initial;border-top-color:initial;border-right-color:initial;border-bottom-color:initial;border-left-color:initial;border-image-source:initial;border-image-slice:initial;border-image-width:initial;border-image-outset:initial;border-image-repeat:initial;display:block;overflow-x:auto;line-height:inherit;word-wrap:normal;height:auto;"><b>public</b> <span style=""><b>enum</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>UnicodeParseResult</b></span>&lt;<span class="colour" style="color:rgb(68, 85, 136)"><b>T</b></span>, <span class="colour" style="color:rgb(68, 85, 136)"><b>Index</b></span>&gt; </span>{
<span class="colour" style="color:rgb(153, 153, 136)"><i>/// Indicates valid input was recognized.</i></span>
<span class="colour" style="color:rgb(153, 153, 136)"><i>///</i></span>
<span class="colour" style="color:rgb(153, 153, 136)"><i>/// `resumptionPoint` is the end of the parsed region</i></span>
<b>case</b> valid(<span class="colour" style="color:rgb(68, 85, 136)"><b>T</b></span>, resumptionPoint: <span class="colour" style="color:rgb(68, 85, 136)"><b>Index</b></span>)  <span class="colour" style="color:rgb(153, 153, 136)"><i>// <span class="colour" style="color:rgb(221, 17, 68)">FIXME:</span> should these be reordered?</i></span>
<span class="colour" style="color:rgb(153, 153, 136)"><i>/// Indicates invalid input was recognized.</i></span>
<span class="colour" style="color:rgb(153, 153, 136)"><i>///</i></span>
<span class="colour" style="color:rgb(153, 153, 136)"><i>/// `resumptionPoint` is the next position at which to continue parsing after</i></span>
<span class="colour" style="color:rgb(153, 153, 136)"><i>/// the invalid input is repaired.</i></span>
<b>case</b> error(resumptionPoint: <span class="colour" style="color:rgb(68, 85, 136)"><b>Index</b></span>)

<span class="colour" style="color:rgb(153, 153, 136)"><i>/// Indicates that there was no more input to consume.</i></span>
<b>case</b> emptyInput

  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// If any input was consumed, the point from which to continue parsing.</i></span>
  <b>var</b> resumptionPoint: <span class="colour" style="color:rgb(68, 85, 136)"><b>Index</b></span>? {
    <b>switch</b> <b>self</b> {
    <b>case</b> .valid(<span class="colour" style="color:rgb(0, 128, 128)">_</span>,<b>let</b> r): <b>return</b> r
    <b>case</b> .error(<b>let</b> r): <b>return</b> r
    <b>case</b> .emptyInput: <b>return</b> <span class="colour" style="color:rgb(0, 128, 128)">nil</span>
    }
  }
}

<span class="colour" style="color:rgb(153, 153, 136)"><i>/// An encoding for text with UnicodeScalar as a common currency type</i></span>
<b>public</b> <span style=""><b>protocol</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>UnicodeEncoding</b></span> </span>{
  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// The maximum number of code units in an encoded unicode scalar value</i></span>
  <b>static</b> <b>var</b> maxLengthOfEncodedScalar: <span class="colour" style="color:rgb(68, 85, 136)"><b>Int</b></span> { <b>get</b> }
  
  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// A type that can represent a single UnicodeScalar as it is encoded in this</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// encoding.</i></span>
  associatedtype <span class="colour" style="color:rgb(68, 85, 136)"><b>EncodedScalar</b></span> : <span class="colour" style="color:rgb(68, 85, 136)"><b>EncodedScalarProtocol</b></span>

  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// Produces a scalar of this encoding if possible; returns `nil` otherwise.</i></span>
  <b>static</b> <span style=""><b>func</b> <span class="colour" style="color:rgb(153, 0, 0)"><b>encode</b></span>&lt;Scalar: EncodedScalarProtocol&gt;<span style="">(
    <span class="colour" style="color:rgb(0, 128, 128)">_</span>:Scalar)</span></span> -&gt; <span class="colour" style="color:rgb(68, 85, 136)"><b>Self</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>EncodedScalar</b></span>?
  
  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// Parse a single unicode scalar forward from `input`.</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>///</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// - Parameter knownCount: a number of code units known to exist in `input`.</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>///   **Note:** passing a known compile-time constant is strongly advised,</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>///   even if it's zero.</i></span>
  <b>static</b> <span style=""><b>func</b> <span class="colour" style="color:rgb(153, 0, 0)"><b>parseScalarForward</b></span>&lt;C: Collection&gt;<span style="">(
    <span class="colour" style="color:rgb(0, 128, 128)">_</span> input: C, knownCount: Int <span class="colour" style="color:rgb(153, 153, 136)"><i>/* = 0, via extension */</i></span>
  )</span></span> -&gt; <span class="colour" style="color:rgb(68, 85, 136)"><b>ParseResult</b></span>&lt;<span class="colour" style="color:rgb(68, 85, 136)"><b>EncodedScalar</b></span>, <span class="colour" style="color:rgb(68, 85, 136)"><b>C</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Index</b></span>&gt;
  <b>where</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>C</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Iterator</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Element</b></span> == <span class="colour" style="color:rgb(68, 85, 136)"><b>EncodedScalar</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Iterator</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Element</b></span>

  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// Parse a single unicode scalar in reverse from `input`.</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>///</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>/// - Parameter knownCount: a number of code units known to exist in `input`.</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>///   **Note:** passing a known compile-time constant is strongly advised,</i></span>
  <span class="colour" style="color:rgb(153, 153, 136)"><i>///   even if it's zero.</i></span>
  <b>static</b> <span style=""><b>func</b> <span class="colour" style="color:rgb(153, 0, 0)"><b>parseScalarReverse</b></span>&lt;C: BidirectionalCollection&gt;<span style="">(
    <span class="colour" style="color:rgb(0, 128, 128)">_</span> input: C, knownCount: Int <span class="colour" style="color:rgb(153, 153, 136)"><i>/* = 0 , via extension */</i></span>
  )</span></span> -&gt; <span class="colour" style="color:rgb(68, 85, 136)"><b>ParseResult</b></span>&lt;<span class="colour" style="color:rgb(68, 85, 136)"><b>EncodedScalar</b></span>, <span class="colour" style="color:rgb(68, 85, 136)"><b>C</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Index</b></span>&gt;
  <b>where</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>C</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Iterator</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Element</b></span> == <span class="colour" style="color:rgb(68, 85, 136)"><b>EncodedScalar</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Iterator</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Element</b></span>
}

<span class="colour" style="color:rgb(153, 153, 136)"><i>/// Parsing multiple unicode scalar values</i></span>
<span style=""><b>extension</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>UnicodeEncoding</b></span> </span>{
  @discardableResult
  <b>public</b> <b>static</b> <span style=""><b>func</b> <span class="colour" style="color:rgb(153, 0, 0)"><b>parseForward</b></span>&lt;C: Collection&gt;<span style="">(
    <span class="colour" style="color:rgb(0, 128, 128)">_</span> input: C,
    repairingIllFormedSequences makeRepairs: Bool = <span class="colour" style="color:rgb(0, 128, 128)">true</span>,
    into output: <span style="">(EncodedScalar)</span></span></span> <b>throws</b>-&gt;<span class="colour" style="color:rgb(68, 85, 136)"><b>Void</b></span>
  ) <b>rethrows</b> -&gt; (remainder: <span class="colour" style="color:rgb(68, 85, 136)"><b>C</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>SubSequence</b></span>, errorCount: <span class="colour" style="color:rgb(68, 85, 136)"><b>Int</b></span>)
  
  @discardableResult    
  <b>public</b> <b>static</b> <span style=""><b>func</b> <span class="colour" style="color:rgb(153, 0, 0)"><b>parseReverse</b></span>&lt;C: BidirectionalCollection&gt;<span style="">(
    <span class="colour" style="color:rgb(0, 128, 128)">_</span> input: C,
    repairingIllFormedSequences makeRepairs: Bool = <span class="colour" style="color:rgb(0, 128, 128)">true</span>,
    into output: <span style="">(EncodedScalar)</span></span></span> <b>throws</b>-&gt;<span class="colour" style="color:rgb(68, 85, 136)"><b>Void</b></span>
  ) <b>rethrows</b> -&gt; (remainder: <span class="colour" style="color:rgb(68, 85, 136)"><b>C</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>SubSequence</b></span>, errorCount: <span class="colour" style="color:rgb(68, 85, 136)"><b>Int</b></span>)
  <b>where</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>C</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>SubSequence</b></span> : <span class="colour" style="color:rgb(68, 85, 136)"><b>BidirectionalCollection</b></span>,
        <span class="colour" style="color:rgb(68, 85, 136)"><b>C</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>SubSequence</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>SubSequence</b></span> == <span class="colour" style="color:rgb(68, 85, 136)"><b>C</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>SubSequence</b></span>,
        <span class="colour" style="color:rgb(68, 85, 136)"><b>C</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>SubSequence</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Iterator</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Element</b></span> == <span class="colour" style="color:rgb(68, 85, 136)"><b>EncodedScalar</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Iterator</b></span>.<span class="colour" style="color:rgb(68, 85, 136)"><b>Element</b></span>
}</code><br></pre><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px"><code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">UnicodeCodec</code>&nbsp;will be updated to refine&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">UnicodeEncoding</code>, and all existing codecs will conform to it.</span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">Note, depending on whether this change lands before or after some of the generics features, generic&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">where</code>&nbsp;clauses may need to be added temporarily.</span></span></span></span><br></p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;position:relative;color:rgb(51, 51, 51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238, 238, 238);font-family:helvetica, arial, freesans, clean, sans-serif;background-color:rgb(255, 255, 255);">Source compatibility<br></h2><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">Adding collection conformance to&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;should not materially impact source stability as it is purely additive: Swift 3’s&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;interface currently fulfills all of the requirements for a bidirectional range replaceable collection.</span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">Altering&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>’s slicing operations to return a different type is source breaking. The following mitigating steps are proposed:</span></span></span></span><br></p><ul style="padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:2em;margin-top:0px;margin-bottom:16px;color:rgb(51, 51, 51);font-family:helvetica, arial, freesans, clean, sans-serif;font-size:12.799999237060547px;background-color:rgb(255, 255, 255);"><li style=""><p style="margin-top:16px;margin-right:0px;margin-bottom:16px;margin-left:0px;">Add a deprecated subscript operator that will run in Swift 3 compatibility mode and which will return a&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;not a&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>.<br></p></li><li style=""><p style="margin-top:16px;margin-right:0px;margin-bottom:16px;margin-left:0px;">Add deprecated versions of all current slicing methods to similarly return a&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>.<br></p></li></ul><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">i.e.:</span></span></span></span><br></p><pre style="overflow-x:auto;overflow-y:auto;font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;margin-top:0px;margin-bottom:16px;font-stretch:normal;line-height:1.45;padding-top:16px;padding-right:16px;padding-bottom:16px;padding-left:16px;background-color:rgb(248, 248, 248);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal;color:rgb(51, 51, 51);height:231px;"><code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;padding-top:0.5em;padding-right:0.5em;padding-bottom:0.5em;padding-left:0.5em;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-top-style:initial;border-right-style:initial;border-bottom-style:initial;border-left-style:initial;border-top-color:initial;border-right-color:initial;border-bottom-color:initial;border-left-color:initial;border-image-source:initial;border-image-slice:initial;border-image-width:initial;border-image-outset:initial;border-image-repeat:initial;display:block;overflow-x:auto;line-height:inherit;word-wrap:normal;height:auto;"><span style=""><b>extension</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>String</b></span> </span>{
  <span class="colour" style="color:rgb(153, 153, 153)"><b>@available</b></span>(swift, obsoleted: <span class="colour" style="color:rgb(0, 128, 128)">4</span>)
  <b>subscript</b>(bounds: <span class="colour" style="color:rgb(68, 85, 136)"><b>Range</b></span>&lt;<span class="colour" style="color:rgb(68, 85, 136)"><b>Index</b></span>&gt;) -&gt; <span class="colour" style="color:rgb(68, 85, 136)"><b>String</b></span> {
    <b>return</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>String</b></span>(characters[bounds])
  }

  <span class="colour" style="color:rgb(153, 153, 153)"><b>@available</b></span>(swift, obsoleted: <span class="colour" style="color:rgb(0, 128, 128)">4</span>)
  <b>subscript</b>(bounds: <span class="colour" style="color:rgb(68, 85, 136)"><b>ClosedRange</b></span>&lt;<span class="colour" style="color:rgb(68, 85, 136)"><b>Index</b></span>&gt;) -&gt; <span class="colour" style="color:rgb(68, 85, 136)"><b>String</b></span> {
    <b>return</b> <span class="colour" style="color:rgb(68, 85, 136)"><b>String</b></span>(characters[bounds])
  }
}</code><br></pre><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">In a review of 77 popular Swift projects found on GitHub, these changes resolved any build issues in the 12 projects that assumed an explicit&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;type returned from slicing operations.</span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">Due to the change in internal implementation, this means that these operations will be&nbsp;<i>O(n)</i>&nbsp;rather than&nbsp;<i>O(1)</i>. This is not expected to be a major concern, based on experiences from a similar change made to Java, but projects will be able to work around performance issues without upgrading to Swift 4 by explicitly typing slices as&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>, which will call the Swift 4 variant, and which will be available but not invoked by default in Swift 3 mode.</span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">The C string interoperability methods outside the ones described in the detailed design will remain in Swift 3 mode, be deprecated in Swift 4 mode, and be removed in a subsequent release.&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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;">UnicodeCodec</code>&nbsp;will be similarly deprecated.</span></span></span></span><br></p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;position:relative;color:rgb(51, 51, 51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238, 238, 238);font-family:helvetica, arial, freesans, clean, sans-serif;background-color:rgb(255, 255, 255);">Effect on ABI stability<br></h2><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">As a fundamental currency type for Swift, it is essential that the&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;type (and its associated subsequence) is in a good long-term state before being locked down when Swift declares ABI stability. Shrinking the size of&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;to be 64 bits is an important part of this.</span></span></span></span><br></p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;position:relative;color:rgb(51, 51, 51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238, 238, 238);font-family:helvetica, arial, freesans, clean, sans-serif;background-color:rgb(255, 255, 255);">Effect on API resilience<br></h2><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">Decisions about the API resilience of the&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;type are still to be determined, but are not adversely affected by this proposal.</span></span></span></span><br></p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;position:relative;color:rgb(51, 51, 51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238, 238, 238);font-family:helvetica, arial, freesans, clean, sans-serif;background-color:rgb(255, 255, 255);">Alternatives considered<br></h2><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">For a more in-depth discussion of some of the trade-offs in string design, see the manifesto and associated&nbsp;<a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170116/thread.html#30497" style="background-color:transparent;color:rgb(65, 131, 196);text-decoration:none;">evolution thread</a>.</span></span></span></span><br></p><p style="margin: 0px 0px 16px;"><span class="highlight" style="background-color:rgb(255, 255, 255)"><span class="colour" style="color:rgb(51, 51, 51)"><span class="font" style="font-family:helvetica, arial, freesans, clean, sans-serif"><span class="size" style="font-size:12.799999237060547px">This proposal does not yet introduce an implicit conversion from&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;to&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>. The decision on whether to add this will be deferred pending feedback on the initial implementation. The intention is to make a preview toolchain available for feedback, including on whether this implicit conversion is necessary, prior to the release of Swift 4.</span></span></span></span><br></p><div style="margin-top:0px;margin-right:0px;margin-left:0px;color:rgb(51, 51, 51);font-family:helvetica, arial, freesans, clean, sans-serif;font-size:12.799999237060547px;background-color:rgb(255, 255, 255);margin-bottom:0px !important;">Several of the types related to&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>, such as the encodings, would ideally reside inside a namespace rather than live at the top level of the standard library. The best namespace for this is probably&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>, but this is also the name of the protocol. At some point if we gain the ability to nest enums and types inside protocols, they should be moved there. Putting them inside&nbsp;<code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:10.880000114440918px;padding-top:0.2em;padding-right:0px;padding-bottom:0.2em;padding-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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>&nbsp;or some other enum namespace is probably not worthwhile in the mean-time.<br></div>
</div>
<div><u>_______________________________________________</u><br></div>
<div>swift-evolution mailing list<br></div>
<div><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br></div>
<div><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div>
</blockquote><div style="font-family:Arial;"><br></div>
</body>
</html>