<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>I'm sorry but I'm really lost: in your example, how could the client break the library by providing a custom type that conforms to the protocol? Why do you say that something like KeyConvertible shouldn't even exist? They exist so clients can extend libraires and make them even more useful. I still haven't seen a case where it's necessary to avoid clients to conform to a protocol.</div><div><br>On 19 Feb 2017, at 14:02, Adrian Zubarev &lt;<a href="mailto:adrian.zubarev@devandartist.com">adrian.zubarev@devandartist.com</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><style>
body {
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        padding:1em;
        margin:auto;
        background:#fefefe;
}

h1, h2, h3, h4, h5, h6 {
        font-weight: bold;
}

h1 {
        color: #000000;
        font-size: 28pt;
}

h2 {
        border-bottom: 1px solid #CCCCCC;
        color: #000000;
        font-size: 24px;
}

h3 {
        font-size: 18px;
}

h4 {
        font-size: 16px;
}

h5 {
        font-size: 14px;
}

h6 {
        color: #777777;
        background-color: inherit;
        font-size: 14px;
}

hr {
        height: 0.2em;
        border: 0;
        color: #CCCCCC;
        background-color: #CCCCCC;
    display: inherit;
}

p, blockquote, ul, ol, dl, li, table, pre {
        margin: 15px 0;
}

a, a:visited {
        color: #4183C4;
        background-color: inherit;
        text-decoration: none;
}

#message {
        border-radius: 6px;
        border: 1px solid #ccc;
        display:block;
        width:100%;
        height:60px;
        margin:6px 0px;
}

button, #ws {
        font-size: 12 pt;
        padding: 4px 6px;
        border-radius: 5px;
        border: 1px solid #bbb;
        background-color: #eee;
}

code, pre, #ws, #message {
        font-family: Monaco;
        font-size: 10pt;
        border-radius: 3px;
        background-color: #F8F8F8;
        color: inherit;
}

code {
        border: 1px solid #EAEAEA;
        margin: 0 2px;
        padding: 0 5px;
}

pre {
        border: 1px solid #CCCCCC;
        overflow: auto;
        padding: 4px 8px;
}

pre > code {
        border: 0;
        margin: 0;
        padding: 0;
}

#ws { background-color: #f8f8f8; }


.bloop_markdown table {
border-collapse: collapse;  
font-family: Helvetica, arial, freesans, clean, sans-serif;  
color: rgb(51, 51, 51);  
font-size: 15px; line-height: 25px;
padding: 0; }

.bloop_markdown table tr {
border-top: 1px solid #cccccc;
background-color: white;
margin: 0;
padding: 0; }
     
.bloop_markdown table tr:nth-child(2n) {
background-color: #f8f8f8; }

.bloop_markdown table tr th {
font-weight: bold;
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }

.bloop_markdown table tr td {
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }

.bloop_markdown table tr th :first-child, table tr td :first-child {
margin-top: 0; }

.bloop_markdown table tr th :last-child, table tr td :last-child {
margin-bottom: 0; }

.bloop_markdown blockquote{
  border-left: 4px solid #dddddd;
  padding: 0 15px;
  color: #777777; }
  blockquote > :first-child {
    margin-top: 0; }
  blockquote > :last-child {
    margin-bottom: 0; }

code, pre, #ws, #message {
    word-break: normal;
    word-wrap: normal;
}

hr {
    display: inherit;
}

.bloop_markdown :first-child {
    -webkit-margin-before: 0;
}

code, pre, #ws, #message {
    font-family: Menlo, Consolas, Liberation Mono, Courier, monospace;
}


.send { color:#77bb77; }
.server { color:#7799bb; }
.error { color:#AA0000; }</style><div class="bloop_markdown"><p>That won’t work, plus the suggested solution makes life even more complicated. I need to be able to index an array, so I’m not willing to simply give up integers and do some extra work behind the scenes and convert a String to an Int. Furthermore there is no need something like <code>KeyConvertible</code> to even exist.</p>

<p></p></div><div class="bloop_original_html"><style>body{font-family:Helvetica,Arial;font-size:13px}</style><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><br></div> <br> <div id="bloop_sign_1487509170434340096" class="bloop_sign"><div style="font-family:helvetica,arial;font-size:13px">--&nbsp;<br>Adrian Zubarev<br>Sent with Airmail</div></div> <br><p class="airmail_on">Am 19. Februar 2017 um 13:58:35, David Hart (<a href="mailto:david@hartbit.com">david@hartbit.com</a>) schrieb:</p> <blockquote type="cite" class="clean_bq"><span><div dir="auto"><div></div><div>



<title></title>


<div>I honestly don't see the use case. The example you showed is
an example of how your circumvented the lack of "closed" protocols
in Swift. But I'd really like to see an example of the necessity
for closed protocols in the first place:</div>
<div id="AppleMailSignature"><br></div>
<div id="AppleMailSignature">In your case, I would simply defined
the API as:</div>
<div id="AppleMailSignature"><br></div>
<div id="AppleMailSignature">protocol KeyConvertible {</div>
<div id="AppleMailSignature">&nbsp; &nbsp; var key: String { get
}</div>
<div id="AppleMailSignature">}</div>
<div id="AppleMailSignature"><br></div>
<div id="AppleMailSignature">public subscript(firstKey: String,
parameters: KeyConvertible...) {}</div>
<div id="AppleMailSignature"><br></div>
<div id="AppleMailSignature">Which would allow clients to implement
their own KeyConvertible conforming types which convert into key
paths.</div>
<div><br>
On 19 Feb 2017, at 09:14, Adrian Zubarev via swift-evolution
&lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt;
wrote:<br>
<br></div>
<blockquote type="cite">
<div>

<div class="bloop_markdown">
<p>If you haven’t followed the other thread Matthew previously
opened than you have missed the example I showed there.</p>
<p>Here it is again:</p>
<pre><code class="swift">public protocol SubscriptParameterType {
       
    // This property was needed to prevent the client from breaking
    // the library by conforming to the protocol, but I'd like to    
    // keep it invisible for the client, or even better prevent the
    // client from conforming to the protocol.
    var parameter: Document.SubscriptParameter { get }
}

extension Document {
       
    public enum SubscriptParameter {
               
        case string(String)
        case integer(Int)
    }
}

extension String : SubscriptParameterType {
       
    public var parameter: Document.SubscriptParameter {
           
        return .string(self)
    }
}

extension Int : SubscriptParameterType {
       
    public var parameter: Document.SubscriptParameter {
           
        return .integer(self)
    }
}

// Somewhere inside the `Document` type
public subscript(firstKey: String, parameters: SubscriptParameterType...) -&gt; Value? { … }
</code></pre>
<p>The absence of closed protocols forced me to create a special
requirement on that protocol to prevent the client from conforming
to that protocol and passing instances of other types my API
wouldn’t want to deal with. That creates unnecessary copies and I
need to unpack the enum payload to find out which type the user
passed. Instead I could simply close the protocol, wouldn’t need
the requirement to exist and I could simply cast the type to
<code>String</code> or <code>Int</code> when needed.</p>
<p>That implementation enables more safe queries of my Document
type like</p>
<p><code>document["key1", intIndexInstance, stringKeyInstance, 10,
"key"]</code></p>
<p>rather than</p>
<p>
<code>document["key1/\(intIndexInstance)/\(stringKeyInstance)/10/key"]</code>.</p>
<hr>
<p>Here is a list of hidden and semi-hidden protocols from the
standard library that could be closed. Formatted version: <a href="https://gist.github.com/DevAndArtist/168c800d784829be536c407311953ab7">
https://gist.github.com/DevAndArtist/168c800d784829be536c407311953ab7</a></p>
<table>
<colgroup>
<col style="text-align:left;">
<col style="text-align:center;"></colgroup>
<thead>
<tr>
<th style="text-align:left;">Path</th>
<th style="text-align:center;">Protocol</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/AnyHashable.swift:16</td>
<td style="text-align:center;">
<code>_HasCustomAnyHashableRepresentation</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/BidirectionalCollection.swift:21</td>
<td style="text-align:center;">
<code>_BidirectionalIndexable</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/BridgeObjectiveC.swift:19</td>
<td style="text-align:center;">
<code>_ObjectiveCBridgeable</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/Collection.swift:20</td>
<td style="text-align:center;"><code>_IndexableBase</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/Collection.swift:176</td>
<td style="text-align:center;"><code>_Indexable</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/CompilerProtocols.swift:193</td>
<td style="text-align:center;">
<code>_ExpressibleByBuiltinIntegerLiteral</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/CompilerProtocols.swift:240</td>
<td style="text-align:center;">
<code>_ExpressibleByBuiltinFloatLiteral</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/CompilerProtocols.swift:283</td>
<td style="text-align:center;">
<code>_ExpressibleByBuiltinBooleanLiteral</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/CompilerProtocols.swift:316</td>
<td style="text-align:center;">
<code>_ExpressibleByBuiltinUnicodeScalarLiteral</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/CompilerProtocols.swift:350</td>
<td style="text-align:center;">
<code>_ExpressibleByBuiltinExtendedGraphemeClusterLiteral</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/CompilerProtocols.swift:398</td>
<td style="text-align:center;">
<code>_ExpressibleByBuiltinStringLiteral</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/CompilerProtocols.swift:407</td>
<td style="text-align:center;">
<code>_ExpressibleByBuiltinUTF16StringLiteral</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/CompilerProtocols.swift:670</td>
<td style="text-align:center;">
<code>_ExpressibleByStringInterpolation</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/CompilerProtocols.swift:709</td>
<td style="text-align:center;">
<code>_ExpressibleByColorLiteral</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/CompilerProtocols.swift:720</td>
<td style="text-align:center;">
<code>_ExpressibleByImageLiteral</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/CompilerProtocols.swift:730</td>
<td style="text-align:center;">
<code>_ExpressibleByFileReferenceLiteral</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/CompilerProtocols.swift:750</td>
<td style="text-align:center;">
<code>_DestructorSafeContainer</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/FixedPoint.swift.gyb:53</td>
<td style="text-align:center;"><code>_Integer</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/FixedPoint.swift.gyb:70</td>
<td style="text-align:center;"><code>_SignedInteger</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/FixedPoint.swift.gyb:108</td>
<td style="text-align:center;">
<code>_DisallowMixedSignArithmetic</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/Hashable.swift:16</td>
<td style="text-align:center;"><code>_Hashable</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/Index.swift:16</td>
<td style="text-align:center;"><code>_Incrementable</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/IntegerArithmetic.swift.gyb:33</td>
<td style="text-align:center;"><code>_IntegerArithmetic</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/Mirror.swift:721</td>
<td style="text-align:center;">
<code>_DefaultCustomPlaygroundQuickLookable</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/MutableCollection.swift:20</td>
<td style="text-align:center;"><code>_MutableIndexable</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/NewtypeWrapper.swift.gyb:16</td>
<td style="text-align:center;">
<code>_SwiftNewtypeWrapper</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/Pointer.swift:16</td>
<td style="text-align:center;"><code>_Pointer</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/RandomAccessCollection.swift:20</td>
<td style="text-align:center;">
<code>_RandomAccessIndexable</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/RangeReplaceableCollection.swift.gyb:27</td>
<td style="text-align:center;">
<code>_RangeReplaceableIndexable</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/ReflectionLegacy.swift:41</td>
<td style="text-align:center;"><code>_Mirror</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/ShadowProtocols.swift:27</td>
<td style="text-align:center;"><code>_ShadowProtocol</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/ShadowProtocols.swift:31</td>
<td style="text-align:center;"><code>_NSFastEnumeration</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/ShadowProtocols.swift:41</td>
<td style="text-align:center;"><code>_NSEnumerator</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/ShadowProtocols.swift:51</td>
<td style="text-align:center;"><code>_NSCopying</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/ShadowProtocols.swift:61</td>
<td style="text-align:center;"><code>_NSArrayCore</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/ShadowProtocols.swift:83</td>
<td style="text-align:center;"><code>_NSDictionaryCore</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/ShadowProtocols.swift:125</td>
<td style="text-align:center;"><code>_NSDictionary</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/ShadowProtocols.swift:137</td>
<td style="text-align:center;"><code>_NSSetCore</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/ShadowProtocols.swift:171</td>
<td style="text-align:center;"><code>_NSSet</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/ShadowProtocols.swift:177</td>
<td style="text-align:center;"><code>_NSNumber</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/ShadowProtocols.swift:187</td>
<td style="text-align:center;"><code>_NSArrayCore</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/ShadowProtocols.swift:188</td>
<td style="text-align:center;"><code>_NSDictionaryCore</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/ShadowProtocols.swift:189</td>
<td style="text-align:center;"><code>_NSSetCore</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/core/StringBridge.swift:194</td>
<td style="text-align:center;"><code>_NSStringCore</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/SDK/Foundation/NSError.swift:353</td>
<td style="text-align:center;">
<code>_ObjectiveCBridgeableError</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/SDK/Foundation/NSError.swift:379</td>
<td style="text-align:center;"><code>__BridgedNSError</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/SDK/Foundation/NSError.swift:446</td>
<td style="text-align:center;"><code>_BridgedNSError</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/SDK/Foundation/NSError.swift:456</td>
<td style="text-align:center;">
<code>_BridgedStoredNSError</code></td>
</tr>
<tr>
<td style="text-align:left;">
/swift/stdlib/public/SDK/Foundation/NSError.swift:564</td>
<td style="text-align:center;"><code>_ErrorCodeProtocol</code></td>
</tr>
</tbody>
</table>
</div>
<div class="bloop_original_html">

<div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;">
<br></div>
<br>
<div id="bloop_sign_1487490659060471040" class="bloop_sign">
<div style="font-family:helvetica,arial;font-size:13px">
--&nbsp;<br>
Adrian Zubarev<br>
Sent with Airmail</div>
</div>
<br>
<p class="airmail_on">Am 19. Februar 2017 um 07:59:45, David Waite
via swift-evolution (<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>)
schrieb:</p>
<blockquote type="cite" class="clean_bq">
<div>
<div><span>I am unsure if this feature is a good idea. Does someone
have a real-world use for this which isn’t just hiding strong
implementation coupling behind a protocol?<br>
<br>
When I consume a protocol, it is under the assumption that the
protocol is documented such that I would be able to work against
*any* implementation of the protocol. With a closed protocol, I
would have to assume that there are significant side effects,
either undocumented or difficult for a third party to duplicate. To
my experience, that sounds brittle.<br>
<br>
Assuming you aren’t switching on the implementing type of a
protocol (which itself can be a sign that your design isn’t
properly using polymorphism), one could get this design by creating
a struct with the interface desired, and passing invocations
through to an internal protocol reference.<br>
<br>
-DW<br>
<br>
&gt; On Feb 18, 2017, at 1:41 PM, Matthew Johnson via
swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt;
wrote:<br>
&gt;<br>
&gt; Now that we’re in phase 2 I’d like to officially propose we
introduce `open` protocols and require conformances to `public`
protocols be inside the declaring module. Let’s use this thread for
feedback on the official proposal. After a healthy round of
discussion I’ll open a PR to submit it for review.<br>
&gt;<br>
&gt;<br>
&gt; # Feature name<br>
&gt;<br>
&gt; * Proposal: [SE-NNNN](NNNN-open-public-protocols.md)<br>
&gt; * Authors: [Matthew Johnson](<a href="https://github.com/anandabits">https://github.com/anandabits</a>)<br>

&gt; * Review Manager: TBD<br>
&gt; * Status: **Awaiting review**<br>
&gt;<br>
&gt; ## Introduction<br>
&gt;<br>
&gt; This proposal introduces `open protocol` and changes the
meaning of `public protocol` to match the meaning of `public class`
(in this case, conformances are only allowed inside the declaring
module).<br>
&gt;<br>
&gt; The pitch thread leading up to this proposal was: [consistent
public access modifiers](<a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170206/031653.html">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170206/031653.html</a>)<br>

&gt;<br>
&gt; ## Motivation<br>
&gt;<br>
&gt; A general principle the Swift community has adopted for access
control is that defaults should reserve maximum flexibility for a
library. The ensures that any capabilities beyond mere visibility
are not available unless the author of the library has explicitly
declared their intent that the capabilities be made available.
Finally, when it is possible to switch from one semantic to another
without breaking clients (but not vice-versa) we should prefer the
more forgiving (i.e. fixable) semantic as the (soft) default.<br>
&gt;<br>
&gt; `public` is considered a "soft default" in the sense that it
is the first access modifier a user will reach for when exposing a
declaration outside of the module. In the case of protocols the
current meaning of `public` does not meet the principle of
preserving maximum flexibility for the author of the library. It
allows users of the library to conform to the protocol.<br>
&gt;<br>
&gt; There are good reasons a library may not wish to allow users
to add conformances to a protocol. For example, it may not wish to
expose the conforming concrete types. While similar behavior could
be accomplished with an enum if cases could be private, that
requires an implementation to use switch statements rather than
polymorphism.<br>
&gt;<br>
&gt; Even if all the conforming types are also public there are
cases where polymorphism is the preferred implementation. For
example, if the set of conforming types is not expected to be fixed
(despite all being inside the library) the authors may not want to
have to maintain switch statements every time they need to add or
remove a confroming type which would be necessary if an enum were
used instead. Polymorphism allows us to avoid this, giving us the
ability to add and remove conforming types within the
implementation of the library without the burden of maintaining
switch statements.<br>
&gt;<br>
&gt; Aligning the access modifiers for protocols and classes allows
us to specify both conformable and non-conformable protocols,
provides a soft default that is consistent with the principle of
(soft) defaults reserving maximum flexibility for the library, and
increases the overall consistency of the language by aligning the
semantics of access control for protocols and classes.<br>
&gt;<br>
&gt; The standard library currently has at least one protocol
(`MirrorPath`) that is documented as disallowing client
conformances. If this proposal is adopted it is likely that
`MirrorPath` would be declared `public protocol` and not `open
protocol`.<br>
&gt;<br>
&gt; Jordan Rose has indicated that the Apple frameworks also
include a number of protocols documented with the intent that users
do not add conformances. Perhaps an importer annotation would allow
the compiler to enforce these semantics in Swift code as
well.<br>
&gt;<br>
&gt; ## Proposed solution<br>
&gt;<br>
&gt; The proposed solution is to change the meaning of `public
protocol` to disallow conformances outside the declaring module and
introduce `open protocol` to allow conformances outside the
decalring module (equivalent to the current meaning of `public
protocol`).<br>
&gt;<br>
&gt; ## Detailed design<br>
&gt;<br>
&gt; The detailed design is relatively straightforward but there
are three important wrinkles to consider.<br>
&gt;<br>
&gt; ### User refinement of public protocols<br>
&gt;<br>
&gt; Consider the following example:<br>
&gt;<br>
&gt; ```swift<br>
&gt; // Library module:<br>
&gt; public protocol P {}<br>
&gt; public class C: P {}<br>
&gt;<br>
&gt; // User module:<br>
&gt; protocol User: P {}<br>
&gt; extension C: User {}<br>
&gt; ```<br>
&gt;<br>
&gt; The user module is allowed to add a refinement to `P` because
this does not have any impact on the impelementation of the library
or its possible evolution. It simply allows the user to write code
that is generic over a subset of the conforming types provided by
the library.<br>
&gt;<br>
&gt; ### Public protocols with open conforming classes<br>
&gt;<br>
&gt; Consider the following example:<br>
&gt;<br>
&gt; ```swift<br>
&gt; public protocol P P{}<br>
&gt; open class C: P {}<br>
&gt; ```<br>
&gt;<br>
&gt; Users of this module will be able to add subclasses of `C`
that have a conformance to `P`. This is allowed becuase the client
of the module did not need to explicitly declare a conformance and
the module has explicitly stated its intent to allow subclasses of
`C` with the `open` access modifier.<br>
&gt;<br>
&gt; ### Open protocols that refine public protocols<br>
&gt;<br>
&gt; Consider the following example:<br>
&gt;<br>
&gt; ```swift<br>
&gt; // library module:<br>
&gt; public protocol P {}<br>
&gt; open protocol Q: P {}<br>
&gt; open protocol R: P {}<br>
&gt;<br>
&gt; // user module:<br>
&gt; struct S: P {} // error `P` is not `open`<br>
&gt; struct T: Q {} // ok<br>
&gt; struct U: R {} // ok<br>
&gt; ```<br>
&gt;<br>
&gt; The user module is allowed to introudce a conformance to `P`,
but only indirectly by also conforming to `Q`. The meaning we have
ascribed to the keywords implies that this should be allowed and it
offers libraries a very wide design space from which to choose. The
library is able to have types that conform directly to `P`, while
placing additional requirements on user types if necessary.<br>
&gt;<br>
&gt; ## Source compatibility<br>
&gt;<br>
&gt; This proposal breaks source compatibility, but in a way that
allows for a simple mechanical migration. A multi-release stratgegy
will be used to roll out this proposal to provide maximum possible
source compatibility from one release to the next.<br>
&gt;<br>
&gt; 1. In Swift 4, introduce the `open` keyword and the `@nonopen`
attribute (which can be applied to `public protocol` to give it the
new semantics of `public`).<br>
&gt; 2. In Swift 4 (or 4.1 if necessary) start warning for `public
protocol` with no annotation.<br>
&gt; 3. In the subsequent release `public protocol` without
annotation becomes an error.<br>
&gt; 4. In the subsequent relase `public protocol` without
annotation takes on the new semantics.<br>
&gt; 5. `@nonopen` becomes a warning, and evenutally an erro as
soon as we are comfortable making those changes.<br>
&gt;<br>
&gt; ## Effect on ABI stability<br>
&gt;<br>
&gt; I would appreciate it if others can offer input regarding this
section. I believe this proposal has ABI consequences, but it's
possible that it could be an additivie ABI change where the ABI for
conformable protocols remains the same and we add ABI for
non-conformable protocols later. If that is possible, the primary
impact would be the ABI of any standard library protocols that
would prefer to be non-conformable.<br>
&gt;<br>
&gt; ## Effect on API resilience<br>
&gt;<br>
&gt; This proposal would may impact one or more protocols in the
standard library, such as `MirrorPath`, which would likely choose
to remain `public` rather than adopt `open`.<br>
&gt;<br>
&gt; ## Alternatives considered<br>
&gt;<br>
&gt; The primary alternatives are to either make no change, or to
add something like `closed protocol`. The issues motivating the
current proposal as a better alternative than either of these
options are covered in the motivation section.<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; swift-evolution mailing list<br>
&gt; <a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>

&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>

<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>

<a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</span></div>
</div>
</blockquote>
</div>
<div class="bloop_markdown"></div>
</div>
</blockquote>
<blockquote type="cite">
<div>
<span>_______________________________________________</span><br>
<span>swift-evolution mailing list</span><br>
<span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br>

<span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br>
</div>
</blockquote>


</div></div></span></blockquote></div><div class="bloop_markdown"><p></p></div></div></blockquote></body></html>