<div dir="ltr">On Mon, Aug 22, 2016 at 11:59 PM, Jonathan Hull 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 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">Hi everyone,<br>
<br>
We talked about this before when we were discussing mixins, and there seemed to be generally positive feelings towards it as a feature for the future.</blockquote><div><br></div><div>It&#39;s been some time now since the original discussion, so perhaps you could refresh our collective memory (or at least, mine): although it *seems* like this feature might be useful, I can&#39;t recall a concrete use case where I&#39;ve felt like I needed this feature--do you have some examples?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">  I am fairly certain this affects the ABI though, so I thought I would bring it up now.<br>
<br>
If two protocols have methods/properties with the same name, but different signatures, we need a way to distinguish between them when attempting to conform to both.<br>
<br>
        protocol A {<br>
                var x:Int {get set}<br>
        }<br>
<br>
        protocol B {<br>
                var x:Double {get set}<br>
        }<br></blockquote><div><br></div><div>Methods can be overloaded that differ in arguments or return type, so it seems like this problem mainly exists with *properties* that differ in type--am I wrong?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
One possibility is to allow a struct/class/enum to conform to the protocol while renaming one (or both) of the clashing methods:<br>
<br>
        struct C: A,B {<br>
                var x:Int<br>
                var y:Double implements B.x<br>
        }<br>
<br>
The conforming method/property would still have to have the same signature, but could have a different name (and parameter labels).  It would also allow protocol methods which have identical signatures and semantics, but different names to be implemented using the same method (i.e ‘implements D.z &amp; E.w’).<br>
<br>
When something is cast to the protocol (say ‘as B’), then calling the property (e.g. ‘x’) would end up calling the implementation of the renamed property ( ‘y’ in this example) on the conforming type.<br></blockquote><div><br></div><div>Reflecting on this proposed change, it occurs to me that something of value would be lost, and I think that this something is actually rather valuable:</div><div><br></div><div>Today, when I see that a type conforms to (for example) Sequence, I know that certain methods and/or properties exist on that type. Protocol conformance guarantees a certain API, not just certain semantics.</div><div><br></div><div>Perhaps one way to mitigate this loss would be to have any renamed members listed *in the declaration of conformance*, something like this (with some additional bikeshedding):</div><div><br></div><div>```</div><div>struct MyGreatType : Sequence (count =&gt; length) {</div><div>  // MyGreatType conforms to Sequence but renames `count` to `length`</div><div>}</div><div>```</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I think we would also want a way to retroactively conform using existing properties/methods in an extension declaring conformance.  Not sure what the best syntax for that would be.  Off the top of my head (though I would love to have something with less cruft):<br>
<br>
        extension D:B {<br>
                @conform(to: B.x, with: D.y)<br>
        }<br>
<br>
or maybe just:<br>
<br>
        extension D:B {<br>
                D.y implements B.x<br>
        }<br></blockquote><div><br></div><div>If renamed members are declared along with protocol conformance, then the syntax for retroactive modeling follows naturally:</div><div><br></div><div>```</div><div>extension D : B (x =&gt; y) { }</div><div>// again, the actual notation here is ugly</div><div>// but the underlying idea, I think, is worth considering</div><div>```</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
All of this is merely to start the discussion, so feel free to propose better syntax or a more elegant solution...<br>
<br>
Thoughts?<br>
<br>
Thanks,<br>
Jon<br>
<br>
<br>
______________________________<wbr>_________________<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/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
</blockquote></div><br></div></div>