I like this solution much better than the prior alternative.<div><br></div><div>When a protocol member is removed or renamed, marking it as deprecated is the proper and natural thing to do. And when a conforming type implements a deprecated requirement, there ought to be a warning.</div><div><br></div><div>This is vastly superior to the idea of mandating a keyword on every conforming method and property.</div><div><br></div><div>Nevin<br><br>On Saturday, February 4, 2017, Charlie Monroe via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">I am currently working on updating some protocol APIs in a framework that&#39;s shared among several of my projects. The issue here is that the protocol has an extension with default implementation. For example:<div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;color:rgb(186,45,162)"><span>protocol</span><span style="color:#000000"> Foo {</span></div></div><div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><span>    </span><span style="color:#ba2da2">func</span><span> doSomethingWithArray(</span><span style="color:#ba2da2">_</span><span> arr: [</span><span style="color:#703daa">String</span><span>])</span></div></div><div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><span>}</span></div></div><div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;min-height:10px"><br></div></div><div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;color:rgb(186,45,162)"><span>extension</span><span style="color:#000000"> </span><span style="color:#4f8187">Foo</span><span style="color:#000000"> {</span></div></div><div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><span style="color:#ba2da2">    func</span><span> doSomethingWithArray(</span><span style="color:#ba2da2">_</span><span> arr: [</span><span style="color:#703daa">String</span><span>]) {</span></div></div><div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><span style="color:#3e1e81">    </span>    <span style="color:rgb(62,30,129)">print</span><span>(arr)</span></div></div><div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">    }</div></div><div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><span>}</span></div></div></blockquote><div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;min-height:10px"><span></span></div></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><span><br></span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><span><span style="font-family:Helvetica;font-size:10px">With this you can easily write </span></span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><span><span style="font-family:Helvetica;font-size:10px"><br></span></span></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><span><span style="color:#ba2da2">struct</span> Bar: <span style="color:#4f8187">Foo</span> { }</span></div></blockquote><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><span><br></span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><br></div><div style="margin:0px;line-height:normal">The issue comes when the struct actually implements the method and you decide to rename it in the protocol:</div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div style="margin:0px;line-height:normal"><br></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><span style="color:#ba2da2">struct</span><span> Bar: </span><span style="color:#4f8187">Foo</span><span> {</span></div></div></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><span style="color:#ba2da2">    func</span><span> doSomethingWithArray(</span><span style="color:#ba2da2">_</span><span> arr: [</span><span style="color:#703daa">String</span><span>]) {</span></div></div></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><span>        fatalError()</span></div></div></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><span>    }</span></div></div></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><span>}</span></div></div></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><span><br></span></div></div></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><span><br></span></div></div></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal;color:rgb(186,45,162)"><span>protocol</span><span style="color:#000000"> Foo {</span></div></div></div></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><span>    </span><span style="color:#ba2da2">func</span><span> doSomething(with arr: [</span><span style="color:#703daa">String</span><span>])</span></div></div></div></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><span>}</span></div></div></div></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><span><br></span></div></div></div></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal;color:rgb(186,45,162)"><span>extension</span><span style="color:#000000"> </span><span style="color:#4f8187">Foo</span><span style="color:#000000"> {</span></div></span></div></div></div></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal"><span style="color:#ba2da2">    func</span><span> doSomething(with arr: [</span><span style="color:#703daa">String</span><span>]) {</span></div></span></div></div></div></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal"><span style="color:#3e1e81">    </span>    <span style="color:rgb(62,30,129)">print</span><span>(arr)</span></div></span></div></div></div></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal"><span>    }</span></div></span></div></div></div></div><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal"><span>}</span></div></span></div></div></div></div></blockquote><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal"><span><br></span></div><div style="margin:0px;line-height:normal"><span><span style="font-family:Helvetica;font-size:10px">The code still compiles, yet the behavior of the app changes incredibly. There is no way (to my knowledge) of marking some protocol members as deprecated. I&#39;ve tried the &quot;obvious&quot; solution:</span></span></div><div style="margin:0px;line-height:normal"><span><span style="font-family:Helvetica;font-size:10px"><br></span></span></div></span></div></div></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div style="margin:0px;line-height:normal"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal;color:rgb(186,45,162)"><span>extension</span><span style="color:#000000"> </span><span style="color:#4f8187">Foo</span><span style="color:#000000"> {</span></div><div style="margin:0px;line-height:normal"><span>    </span><span style="color:rgb(186,45,162)">@available</span><span>(*, deprecated, renamed: </span><span style="color:rgb(209,47,27)">&quot;doSomething(with:)&quot;</span><span>)</span></div><div style="margin:0px;line-height:normal"><span style="color:#ba2da2">    func</span><span> doSomethingWithArray(</span><span style="color:#ba2da2">_</span><span> arr: [</span><span style="color:#703daa">String</span><span>]) {</span></div><div style="margin:0px;line-height:normal"><span style="color:#ba2da2">    </span>    <span style="color:rgb(186,45,162)">self</span><span>.</span><span style="color:rgb(49,89,93)">doSomething</span><span>(with: arr)</span></div><div style="margin:0px;line-height:normal"><span>    }</span></div><div style="margin:0px;line-height:normal"><span>}</span></div><div><span><br></span></div></div></span></div></span></div></div></div></div></blockquote>But unfortunately, this doesn&#39;t emit any warning on the Bar structure. I personally believe that this is a major flaw, given that Swift is being claimed as Protocol-Oriented language, there is no way to declare that a protocol method is deprecated/renamed. Mainly with protocols with default implementations (or in ObjC optional).<div><br></div><div>I know there were discussions about marking members that should implement the protocol requirements with a keyword, but unfortunately, most members here were against such a proposal as it would introduce a lot of visual clutter.</div><div><br></div><div>I&#39;m suggesting that implementing a same-named member from a protocol marked as &quot;deprecated&quot; that also has a default implementation would emit a warning.</div><div><br></div><div>Does anyone else view this as an issue in the language?</div><div><br></div><div><br></div><div><br></div><div><br></div></div></blockquote></div>