<div dir="ltr"><div class="gmail_default" style="font-family:georgia,serif">&gt; <span style="font-size:12.800000190734863px;font-family:arial,sans-serif">I am not sure why protocol extension need to differ so much and present dispatch rules that are potentially very confusing. </span></div><div class="gmail_default" style="font-family:georgia,serif"><span style="font-size:12.800000190734863px;font-family:arial,sans-serif"><br></span></div><div class="gmail_default"><span style="font-size:12.800000190734863px">I think that both the Java and Swift designers want to get the benefits of multiple inherences, in the meaning time, they don&#39;t want to support multiple objects inherence. </span></div><div class="gmail_default"><span style="font-size:12.800000190734863px"><br></span></div><div class="gmail_default">For Java only, as Java allows implicit override, the `@override` is optional. Related bugs are hard to find if you don&#39;t use  `@override`.</div><div class="gmail_default"><br></div><div class="gmail_default">For me, the current rule is simple. </div><div class="gmail_default">1. If there is a `override`, it is &quot;class dynamic binding&quot;. If there is no `override`, it is not. The dynamic type of `self` is irrelevant.</div><div class="gmail_default">2. The method in &#39;protocol extension` is default, which means fail safe. It is not a method of a class until the class implements it.</div><div class="gmail_default"><br></div><div class="gmail_default">Zhaoxin</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Sep 21, 2016 at 4:10 AM, Goffredo Marocchi <span dir="ltr">&lt;<a href="mailto:panajev@gmail.com" target="_blank">panajev@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div><div style="direction:inherit">This would make for hilarious debugging session if you have the misfortune of using a third party binary framework that gets updated and provide default implementations for some methods in the protocol extensions.</div><div style="direction:inherit"><br></div><div style="direction:inherit">When Java 8 also decided to blur the lines between classes (implementations) and interfaces (equivalent of protocols on this side of the fence more or less... anyways they represent behaviours/API contracts), they also provided a very simple rule to determine on the code would behave at runtime.</div><div style="direction:inherit"><h2></h2><blockquote type="cite"><h2><a name="m_-7356412064479119979_extending" style="background-color:rgba(255,255,255,0)"><font color="#000000" size="3">Extending Interfaces That Contain Default Methods</font></a></h2><p><span style="background-color:rgba(255,255,255,0)">When you extend an interface that contains a default method, you can do the following:</span></p><ul><li><span style="background-color:rgba(255,255,255,0)">Not mention the default method at all, which lets your extended interface inherit the default method.</span></li><li><span style="background-color:rgba(255,255,255,0)">Redeclare the default method, which makes it <code>abstract</code>.</span></li><li><span style="background-color:rgba(255,255,255,0)">Redefine the default method, which overrides it.</span></li></ul></blockquote></div><div style="direction:inherit"><a href="https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html" target="_blank">https://docs.oracle.com/<wbr>javase/tutorial/java/IandI/<wbr>defaultmethods.html</a></div><div style="direction:inherit"><br></div><div style="direction:inherit">I am not sure why protocol extension need to differ so much and present dispatch rules that are potentially very confusing. </div><div style="direction:inherit"><br></div><div style="direction:inherit">Casting at runtime should *never* change what implementation of a method gets called. </div><div style="direction:inherit">For a safe by default language the fact that this can occur is quite puzzling and worrying. I am not sure the cost of implementing the current static/dynamic dispatch rules for default methods in protocol extensions is worth it to say it bluntly, but please enlighten me if I am missing an obvious huge pink elephant in the room here.</div><div style="direction:inherit"><br></div>Sent from my iPhone</div><div><div class="h5"><div><br>On 20 Sep 2016, at 16:18, Nevin Brackett-Rozinsky via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><div dir="ltr">I think there is a deeper issue that may be worth exploring here.<div><br></div><div>Notably, when one class presents a member function, its subclasses ought to use “override” when they reimplement that method themselves, regardless of where the superclass’s version comes from.</div><div><div><br></div><div>In the original post, the class “A” expresses (by conforming to protocol “Foo”) that it has a member function “bar()”, and “B” is a subclass of “A” which wants its own definition of “bar()”.</div><div><br></div><div>It seems to me that “B” should not care whether “A” rolled its own implementation of “bar()” or used the default implementation provided by “Foo”.</div><div><br></div><div>From the perspective of “B”, its superclass “A” promises to have a member function “bar()”, so “B” should need to use the `override` keyword just like it would when overriding any other method.</div><div><br></div><div>To illustrate this more clearly, suppose that “Foo” and “A: Foo” are defined in a 3rd-party library, while “B: A” is written in a client module.</div><div><br></div><div>If the library changes to give “A” its own custom implementation of “bar()”, that *should not* affect client code—because the class “A” still conforms to “Foo” so it still is known to have a “bar()” method—but right now it *does*:</div><div><br></div><div>With the status quo, the simple change of moving a function between a protocol extension and a conforming class currently requires downstream source-code modifications in clients (in this case, adding `override` to “B.bar()”).</div><div><br></div><div>I propose that `override` should be required in subclasses on any method which the superclass proffers as a customization point, no matter the provenance of that claim.</div><div><br></div><div>Nevin</div><div><br></div><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Sep 20, 2016 at 8:01 AM, Zhao Xin 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 dir="ltr"><div class="gmail_default"><font face="georgia, serif">Thank you to  Игорь Никитин and Adrian Zubarev. Now I can convince myself for this behavior.</font></div><div class="gmail_default"><font face="georgia, serif"><br></font></div><div class="gmail_default"><span style="font-family:georgia,serif">As Adrian&#39;s example shows, there is no `</span><font face="georgia, serif">bar()` implemented in `class A`, so there is no `override func bar()</font><span style="font-family:georgia,serif">` in class B`. My thought that </span><span style="color:rgb(0,0,0);font-family:georgia,serif;font-size:13px"> </span><span style="color:rgb(0,0,0);font-family:georgia,serif;font-size:13px">`self.bar()` would do the same as `(self as! B).bar()`, is called &quot;dynamic binding&quot;, which is basing on the `override`. Since there is no `override`, there is no &quot;dynamic binding&quot;. I thought &quot;dynamic binding&quot; was basing on dynamic type of `self`. It was not. I was wrong.</span></div><div class="gmail_default"><span style="color:rgb(0,0,0);font-family:georgia,serif;font-size:13px"><br></span></div><div class="gmail_default"><span style="color:rgb(0,0,0);font-family:georgia,serif;font-size:13px">The behavior is clear now. In class A&#39;s `</span><font color="#000000" face="georgia, serif">self.bar()`, the runtime finds that there is no implementation of `bar()` in `class A`, so it calls the `bar` in protocol extension. In class A&#39;s `(self as! B).bar()`, as `class B` contains the implementation of `bar()`, the runtime calls it.</font></div><div class="gmail_default"><span style="color:rgb(0,0,0);font-family:georgia,serif;font-size:13px"><br></span></div><div class="gmail_default"><span style="color:rgb(0,0,0);font-family:georgia,serif;font-size:13px">Zhaoxin</span></div></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div>On Tue, Sep 20, 2016 at 4:21 PM, Adrian Zubarev 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></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div style="word-wrap:break-word"><div><p>I can’t tell you the reason, but to me it feels like it’s doing the following thing:</p>

<pre><code>+ - - (Type: B) - - +
|                   |
| func bar()    + - + (Type: A) - - +                        &lt; - - - - - - - - - - - - - - - - - - - - +
|               |                   |                                                                  |
+ - - - - - - - + func output() + - + (Protocol: Foo) - - +  — - self.bar() - + - (self as! B).bar() - +
                |               |                         |                   |
                + - - - - - - - + (default) func bar()    |  &lt;- - - - - - - - +
                                |                         |
                                + - - - - - - - - - - - - +
</code></pre>

<pre><code>class A:Foo {
     
    func bar() {}
     
    func output() {
        print(type(of:self))
        self.bar()
        (self as! B).bar()
    }
}

class B:A {

    override func bar() {
        print(&quot;I am B.&quot;)
    }
}
</code></pre>

<p>Would solve this temporarily.</p>

<p>And there we are again with the same discussion if custom implementation of protocol members, which have default implementation, should have the <code>override</code> keyword or not.</p>

<p>Imagine your code like this (not valid code):</p>

<pre><code>protocol Foo {
    func bar()
}

extension Foo {
    func bar() {
        print(&quot;I am bar.&quot;)
    }
}

class A : Foo {
     
    func output() {
         
        print(type(of:self))
        default.bar() // fallback an call directly the default implementation whenever needed
        self.bar() // will print &quot;I am bar.&quot; on A().output() but should print &quot;I am B.&quot; if Self == B
        (self as! B).bar()
    }
}

class B : A {

    override func bar() {
        print(&quot;I am B.&quot;)
    }
}
</code></pre>

<p>I still think default implementations should be called through something like <code>default.</code> + whenever you override a default implementation you’d need <code>override</code>. There is a discussion going on: <code>Mark protocol methods with their protocol</code>. I clearly did not solved your issue, but I might have wake your interest to participate. ;)</p><span><font color="#888888">

<p></p></font></span></div><div><span><font color="#888888"><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto"><br></div> <br> <div><div style="font-family:helvetica,arial;font-size:13px">-- <br>Adrian Zubarev<br>Sent with Airmail</div></div></font></span><div><div> <br><p>Am 20. September 2016 um 04:13:22, Zhao Xin via swift-users (<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>) schrieb:</p> </div></div><blockquote type="cite"><span><div><div></div><div><div><div>





<div dir="ltr">
<div class="gmail_default" style="font-family:georgia,serif">See
below code.</div>
<div class="gmail_default" style="font-family:georgia,serif">
<br></div>
<div class="gmail_default">
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(4,51,255)">
<span>protocol</span>
<span style="color:rgb(0,0,0)">Foo
{</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
 </span> <span style="color:rgb(4,51,255)">func</span>
<span>bar()</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span>}</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">
<br></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(4,51,255)">
<span>extension</span>
<span style="color:rgb(52,149,175)">Foo</span>
<span style="color:rgb(0,0,0)">{</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
 </span> <span style="color:rgb(4,51,255)">func</span>
<span>bar()
{</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(180,38,26)">
<span style="color:rgb(0,0,0)"> 
     </span> <span style="color:rgb(52,149,175)">print</span><span style="color:rgb(0,0,0)">(</span><span>&quot;I
am bar.&quot;</span><span style="color:rgb(0,0,0)">)</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
  }</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span>}</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">
<br></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span style="color:rgb(4,51,255)">class</span>
<span>A:</span><span style="color:rgb(52,149,175)">Foo</span>
<span>{</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
 </span> <span style="color:rgb(4,51,255)">func</span>
<span>output()
{</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
     </span> <span style="color:rgb(52,149,175)">print</span><span>(type(of:</span><span style="color:rgb(4,51,255)">self</span><span>))</span>
<span style="color:rgb(0,143,0)">//
prints &quot;B&quot;.</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,143,0)">
<span style="color:rgb(0,0,0)"> 
     </span> <span style="color:rgb(4,51,255)">self</span><span style="color:rgb(0,0,0)">.</span><span style="color:rgb(52,149,175)">bar</span><span style="color:rgb(0,0,0)">()</span>
<span>// prints
&quot;I am bar.&quot;</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
      (self</span> <span style="color:rgb(4,51,255)">as</span><span>!</span>
<span style="color:rgb(52,149,175)">B</span><span>).</span><span style="color:rgb(52,149,175)">bar</span><span>()</span>
<span style="color:rgb(0,143,0)">//
prints &quot;I am B.&quot;</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
  }</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span>}</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">
<br></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span style="color:rgb(4,51,255)">class</span>
<span>B:</span><span style="color:rgb(52,149,175)">A</span>
<span>{</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
 </span> <span style="color:rgb(4,51,255)">func</span>
<span>bar()
{</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
     </span> <span style="color:rgb(52,149,175)">print</span><span>(</span><span style="color:rgb(180,38,26)">&quot;I
am B.&quot;</span><span>)</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
  }</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span>}</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">
<br></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span style="color:rgb(4,51,255)">let</span>
<span>b =</span>
<span style="color:rgb(52,149,175)">B</span><span>()</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(52,149,175)">
<span>b</span><span style="color:rgb(0,0,0)">.</span><span>output</span><span style="color:rgb(0,0,0)">()</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(52,149,175)">
<br></p>
<p style="margin:0px;line-height:normal"><font color="#000000" face="georgia, serif">I thought `self.bar()` would do the same as
`(self as! B).bar()`. It didn&#39;t. In my opinion,
 `type(of:self) is B.type`, so they should be the same,
shouldn&#39;t they?</font></p>
<p style="margin:0px;line-height:normal"><font color="#000000" face="georgia, serif"><br></font></p>
<p style="margin:0px;line-height:normal"><font color="#000000" face="georgia, serif">Zhaoxin</font></p>
</div>
</div></div></div>


______________________________<wbr>_________________<span><br>swift-users mailing list<br><a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-users" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-users</a><br></span></div></div></span></blockquote></div><div><p></p></div></div><br></div></div>______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-evolution</a><br>
<br></blockquote></div><br></div>
<br>______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-evolution</a><br>
<br></blockquote></div><br></div>
</div></blockquote><blockquote type="cite"><div><span>______________________________<wbr>_________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a></span><br></div></blockquote></div></div></div></blockquote></div><br></div>