<div dir="ltr">For type A problems: why not require that you annotate with overload? In Java they used to be like Swift; where a method that overrode an interface declaration, no override was required. But they changed, due to these problems, to always require override when implementing a previously declared method, whether this was the first implementation of not. IE:<div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div style="font-size:12.8px">protocol Channel {</div></div><div><div style="font-size:12.8px">  func receive() -&gt; NSData</div></div><div><div style="font-size:12.8px">}</div></div><div style="font-size:12.8px"><br></div><div><div style="font-size:12.8px">extension Channel {</div></div><div><div><div style="font-size:12.8px">  func receive() -&gt; NSData { return NSData() } // Error - no override and declaration in protocol</div></div><div style="font-size:12.8px"><br></div><div></div><div><div style="font-size:12.8px">  override func receive() -&gt; NSData { return NSData() } // OK - note override</div></div><div></div><div style="font-size:12.8px"><span style="font-size:12.8px">}</span><br></div></div><div><div style="font-size:12.8px"><br></div></div><div><div style="font-size:12.8px">// Silently fails to replace the default implementation:</div></div><div><div style="font-size:12.8px">struct ClumsyChannel: Channel {</div></div><div><div style="font-size:12.8px">  override func recieve() -&gt; NSData { return NSData(bytes: &quot;oops&quot;, length: 4) } // Error -<span style="font-size:12.8px"> Wrong spelling</span></div></div><div><div style="font-size:12.8px">  </div></div><div><div style="font-size:12.8px">  override func receive() -&gt; [UInt8] { return Array(&quot;whoopsie&quot;.utf8) } // Error -<span style="font-size:12.8px"> Wrong return type</span></div></div><div><div style="font-size:12.8px">  </div></div><div><div><div><div style="font-size:12.8px">  override func receive() throws -&gt; NSData { throw &quot;doh&quot; } // Error -<span style="font-size:12.8px"> Wrong throwiness</span></div></div><div style="font-size:12.8px"><span style="font-size:12.8px"><br></span></div><div></div><div></div><div><div style="font-size:12.8px">  <span style="font-size:12.8px">func receive() -&gt; NSData</span><span style="font-size:12.8px"> { </span><span style="font-size:12.8px">return NSData(bytes: &quot;Forgot&quot;, length: 6)</span><span style="font-size:12.8px"> } </span>// Error -<span style="font-size:12.8px"> no override and declaration in protocol</span></div></div><div style="font-size:12.8px"><span style="font-size:12.8px"><br></span></div><div></div><div></div><div style="font-size:12.8px"><span style="font-size:12.8px">  </span><span style="font-size:12.8px">override func receive() -&gt; NSData</span><span style="font-size:12.8px"> { </span><span style="font-size:12.8px">return NSData(bytes: &quot;OK&quot;, length: 2)</span><span style="font-size:12.8px"> } // OK - note override</span><br></div></div><div></div><div style="font-size:12.8px"><span style="font-size:12.8px">}</span><br></div></div></blockquote><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">This implies that methods implemented in extensions gain dynamic dispatch; which I believe is under consideration anyway.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">As an aside: I think that protocol extensions are only popular because you can&#39;t put bodies in protocols. If bodies are allowed, I would think that extensions to protocols will become the exception rather than the rule.</div></div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature">  -- Howard.<br></div></div>
<br><div class="gmail_quote">On 4 March 2016 at 11:08, Joe Groff via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> 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">Under the umbrella of completing generics, I think we should make room for improving our diagnostics around protocol extensions. They&#39;re a well-received feature, but they introduce a lot of surprising behavior, and introduce opportunity for subtle bugs. We didn&#39;t have time to put much diagnostic work in last year, but now that users have had time to work with the feature, we have evidence of some of the more surprising and problematic behavior. Among the most common things we&#39;ve seen reported:<div><br></div><div>A) When a protocol requirement has an extension implementation requirement available, we&#39;ll silently ignore when a conforming type attempts to conform to the protocol but misses, by type or spelling:</div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>protocol Channel {</div><div>  func receive() -&gt; NSData</div><div>}</div><div>extension Channel {</div><div>  func receive() -&gt; NSData { return NSData() }</div><div>}</div><div><br></div><div>// Silently fails to replace the default implementation:</div><div>struct ClumsyChannel: Channel {</div><div>  // Wrong spelling</div><div>  func recieve() -&gt; NSData { return NSData(bytes: &quot;oops&quot;, length: 4) }</div><div>  // Wrong return type</div><div>  func receive() -&gt; [UInt8] { return Array(&quot;whoopsie&quot;.utf8) }</div><div>  // Wrong throwiness</div><div>  func receive() throws -&gt; NSData { throw &quot;doh&quot; }</div><div>}</div><div><br></div></blockquote>B) Protocol requirements aren&#39;t real class members, and can&#39;t be overridden by subclasses unless the base class satisfies the requirement with one of its own methods rather than with a protocol extension method, but we silently allow subclasses to shadow:<div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>class BaseChannel: Channel { } // gets default imp from extension</div><div><br></div><div>class SubChannel: BaseChannel {</div><div>  // Doesn&#39;t &#39;override&#39; protocol requirement; silently shadows it</div><div>  func receive() -&gt; NSData { return NSData(bytes: &quot;oof&quot;, length: 3) }</div><div>}</div><div><br></div></blockquote>C) Similarly, protocol extension methods aren&#39;t protocol requirements, so extension methods that don&#39;t match a requirement can&#39;t be specialized in a way available to generic code, but we silently allow concrete type implementations to shadow:<div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>extension Channel {</div><div>  func receiveAsString() -&gt; String {</div><div>    return String(data: receive(), encoding: NSUTF8Encoding)</div><div>  }</div><div>}</div><div><br></div><div>struct StringyChannel {</div><div>  func receive() -&gt; NSData { return NSData(bytes: &quot;data&quot;, 4) }</div><div>  // Does not affect generic code calling receiveAsString</div><div>  func receiveAsString() -&gt; String { return &quot;string&quot; }</div><div>}</div><div><br></div><div>func foo&lt;T: Channel&gt;(chan: T) {</div><div>  print(chan.receiveAsString())</div><div>}</div><div><br></div><div>foo(StringyChannel()) // Prints &quot;data&quot;</div><div><br></div></blockquote>(B) and (C) could be mitigated by shadowing warnings, and we&#39;ve also floated ideas for making them behave as intended, by implicitly forwarding protocol requirements into class methods to address (B) and/or introducing dynamic dispatch for protocol extensions to address (C). (A) is a bit trickier, since with overloading it&#39;s tricky to divine whether a declaration was really intended to match another one with a different type in isolation. We&#39;ve discussed a couple approaches to this problem:<div><br></div><div>- Adopting an explicit &#39;implements&#39; modifier, in the spirit of &#39;override&#39;, to mark a declaration as being intended to fulfill a requirement. This adds boilerplate we&#39;d like to avoid, and also interferes with retroactive modeling.</div><div>- Encourage &quot;one extension per conformance&quot; style, where each protocol conformance&#39;s requirements are defined in a dedicated extension. We can then warn about any declarations in an extension that don&#39;t satisfy a requirement:</div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>struct InconsistentChannel {}</div><div><br></div><div>extension InconsistentChannel: Channel {</div><div>  func receive() -&gt; NSData { ... } // OK</div><div>  func recieve() -&gt; NSData { ... } // Warning: Declaration in conformance extension doesn&#39;t satisfy any requirements from &#39;Channel&#39;</div><div>  func receive() -&gt; NSData? { ... } // Warning</div><div>}</div><div><br></div></blockquote>There are likely others too. It&#39;d be great if we could give users better guidance about this feature.<span class="HOEnZb"><font color="#888888"><div><br></div><div>-Joe</div></font></span></div><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" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br></blockquote></div><br></div>