<div dir="ltr">On Fri, Aug 26, 2016 at 4:24 AM, Charles Srstka <span dir="ltr">&lt;<a href="mailto:cocoadev@charlessoft.com" target="_blank">cocoadev@charlessoft.com</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><span class=""><blockquote type="cite">On Aug 26, 2016, at 4:02 AM, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt; wrote:<br></blockquote><div><blockquote type="cite"><br><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">That is not exactly what Brent was speaking of. We are talking about this scenario:</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">File A:</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">```</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">internal struct S {</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">  func foo() { }</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">}</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">```</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">File B:</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">```</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">private protocol P {</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">  func foo()</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">}</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">extension P {</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">  func foo() { }</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">}</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">// With your proposal, I can&#39;t write the following line:</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">extension S : P { }</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">// In file A, S.foo() isn&#39;t overriding anything, so I can&#39;t add `override`</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">// But in file B, S can&#39;t conform to P,</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">// because S.foo() isn&#39;t overriding P.foo() without `override` in file A</div></div></blockquote></div><br></span><div>First of all, I cannot take credit for the proposal, as the thread was started by David, not me, so if the proposal is anyone’s, it’s his. With that said, what he proposes is:</div><span class=""><div><br></div><div><blockquote type="cite"><div>On Aug 22, 2016, at 4:30 PM, David Cordero via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br><div><div><b>Proposal:</b></div><div>Adding a keyword to the methods conforming protocols. As an example please check the following piece of code which uses the keyword `conform` to explicitly indicate that `myMethod` is a method conforming a protocol.</div></div></blockquote></div><div><div><div><br></div></div></div></span><div>The wording here is that the keyword is needed for methods conforming to protocols. My reading of that is that:</div><div><br></div><div>File A:</div><div><br></div><div>protocol P {</div><span class=""><div><span style="white-space:pre-wrap">        </span>func foo()</div><div>}</div><div><br></div><div>struct S: P {</div></span><div><span style="white-space:pre-wrap">        </span>conform func foo() {</div><div><span style="white-space:pre-wrap">                </span>// I am declared as conforming to P, so in adding this method I am doing so to conform to P. Thus, I need the keyword.</div><div><span style="white-space:pre-wrap">        </span>}</div><div>}</div><div><br></div><div>- - whereas: - -</div><div><br></div><div>File A:</div><div><br></div><div>struct S {</div><div><span style="white-space:pre-wrap">        </span>func foo() {</div><div><span style="white-space:pre-wrap">                </span>// I am not declared as conforming to any protocol; I just think that being able to foo is an ability that I need to have.</div><span class=""><div><span style="white-space:pre-wrap">        </span>}</div><div>}</div><div><br></div><div>File B:</div><div><br></div><div>private protocol P {</div><div><span style="white-space:pre-wrap">        </span>func foo()</div><div>}</div><div><br></div></span><div>extension S: P {</div><div><span style="white-space:pre-wrap">        </span>// The area of contention.</div><div>}</div><div><br></div><div>- - - - - -</div><div><br></div><div>The proposal doesn’t really mention what to do here, so we can argue a bit about it. There are multiple viewpoints one could take on this. A few could be:</div><div><br></div><div>1. The extension should get some kind of keyword, “retro” or “@retro” or something better-sounding that someone smarter than I comes up with.</div><div><br></div><div>2. The extension is unmarked, but declares foo() inside it with some sort of annotation to indicate that it represents a method that already exists.</div><div><br></div><div>3. Just leave the extension exactly as written, since it’s not declaring any methods, and thus doesn’t have to indicate what those nonexistent method declarations conform to.</div><div><br></div><div>I began this discussion leaning toward #1, but now I’m starting to consider #3, since the purpose of the keyword is to declare one’s intentions. The intentions of an empty extension that does nothing but conform to a protocol is actually quite clear; the methods have to be already declared somewhere else, or it makes no sense. At any rate, the “problem” in your scenario is entirely confined to File B, so if any annotations are necessary, that is where they belong. File A does not know about the protocol, it does not know that it is conforming to the protocol, and indeed, the protocol is none of File A’s business. So since File A is not intending to conform to the protocol, File A does not have to declare its intent to conform to the protocol. If we require that, it’s all in File B’s court.</div></div></blockquote><div><br></div><div>As I said, this discussion has already happened several times. I&#39;m literally just repeating what people said eight months ago, six months ago, and four months ago. There&#39;s not a good answer to this and perhaps several other issues, which is why I don&#39;t see a way forward for the proposal. After all, I was the one proposing the same idea last winter, so I&#39;ve had a few months to think about it.</div><div><br></div><div>If option (3) were allowed, then no keyword could ever be mandatory; it&#39;s always possible to refactor so that a conformance declaration is an empty extension. So we&#39;re back at an optional keyword, which has its own problems. This kind of thinking is how I&#39;ve come to the conclusion that the status quo, with better diagnostics, is the least bad solution.</div></div></div></div>