<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Feb 29, 2016, at 11:28 PM, Rasmus Kjeldsen &lt;<a href="mailto:rasmus.kjeldsen@gmail.com" class="">rasmus.kjeldsen@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Maybe the “extension protocol &lt;P&gt;” syntax is more confusing than to just let<span style="color: rgb(55, 62, 77); background-color: rgb(254, 254, 254);" class="">&nbsp;protocol types implicitly conform to the static methods of their own protocol?</span></div></div></div></blockquote><div><br class=""></div><div>Not every protocol type is a natural model of the protocol it represents. When a protocol has `static` or `init` requirements, for instance, the protocol type can't conform to its own protocol, since it's an abstract type with no type-level implementations of its own. Contravariant `Self` and associated type constraints are also problematic. Furthermore, in our resilience model, public protocols are allowed to add new requirements in future versions that cause a formerly self-conforming protocol to no longer conform. For these reasons, we really need the ability to explicitly declare that a protocol type is intended to be usable as a model of its own protocol.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);" class="">protocol<span style="font-size: 13px; line-height: normal;" class=""> P {}</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; min-height: 15px;" class=""><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);" class="">extension<span style="font-size: 13px; line-height: normal;" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">P</span><span style="font-size: 13px; line-height: normal;" class=""> {</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);" class=""><span style="font-size: 13px; line-height: normal;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span>static<span style="font-size: 13px; line-height: normal;" class=""> </span>func<span style="font-size: 13px; line-height: normal;" class=""> a() {}</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo;" class="">}</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; min-height: 15px;" class=""><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);" class="">extension<span style="font-size: 13px; line-height: normal;" class=""> </span>protocol<span style="font-size: 13px; line-height: normal;" class=""> &lt;</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">P</span><span style="font-size: 13px; line-height: normal;" class="">&gt; {</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);" class=""><span style="font-size: 13px; line-height: normal;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span>static<span style="font-size: 13px; line-height: normal;" class=""> </span>func<span style="font-size: 13px; line-height: normal;" class=""> b() {}</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo;" class="">}</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; min-height: 15px;" class=""><br class=""></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo;" class=""><span style="font-size: 12px; line-height: normal; color: rgb(187, 44, 162);" class="">class</span> C : <span style="font-size: 12px; line-height: normal; color: rgb(79, 129, 135);" class="">P</span> { }</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; min-height: 15px;" class=""><br class=""></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">C</span><span style="" class="">.a() </span><span style="font-size: 12px; line-height: normal;" class="">// ok</span></div></div></div></div></blockquote><div><br class=""></div><div>Yeah.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-size: 13px; line-height: normal; color: rgb(79, 129, 135);" class="">C</span><span style="font-size: 13px; line-height: normal;" class="">.b() </span>// ok or not allowed?</div></div></div></div></blockquote><div><br class=""></div><div>Good question. The type object `C.self: C.Type` is a subtype of `P.Type`, so one could argue that this should be allowed by implicit up-conversion.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-size: 13px; line-height: normal;" class="">P.a() </span>// not allowed</div></div></div></div></blockquote><div><br class=""></div>Yeah.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">P</span><span style="" class="">.b() </span><span style="font-size: 12px; line-height: normal;" class="">// ok</span></div></div></div></div></blockquote><div><br class=""></div>Yeah.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><span style="font-size: 12px; line-height: normal;" class=""><br class=""></span></div><div class="">And if C.b() is not allowed, what about if we also do:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);" class="">extension<span style="font-size: 13px; line-height: normal;" class="">&nbsp;</span><span style="color: rgb(112, 61, 170);" class="">P</span><span style="font-size: 13px; line-height: normal;" class="">&nbsp;{</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);" class=""><span style="font-size: 13px; line-height: normal;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span></span>static<span style="font-size: 13px; line-height: normal;" class="">&nbsp;</span>func<span style="font-size: 13px; line-height: normal;" class="">&nbsp;b() {}</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo;" class="">}</div></div><div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-size: 13px; line-height: normal; color: rgb(79, 129, 135);" class="">C</span><span style="font-size: 13px; line-height: normal;" class="">.b()&nbsp;</span>// ok?</div></div><div class=""><br class=""></div><div class="">Should that be allowed?</div></div></div></blockquote><div><br class=""></div><div>Yeah, in that case `extension P` is extending all types that conform to P.</div><div><br class=""></div><div>-Joe</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">Regards</div><div class="">Rasmus</div><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 28 Feb 2016, at 02:05, Joe Groff via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Rasmus Kjeldsen via swift-evolution<br class="">&lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><blockquote type="cite" class=""><br class="">I propose to allow static protocol extension methods to be used directly on the protocol.<br class="">This would enable the Factory-pattern to be elegantly implemented as in the example below:<br class=""><br class="">protocol P {}<br class=""><br class="">class A : P {}<br class="">class B : P {}<br class=""><br class="">extension P {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>static func factory(type: Bool) -&gt; P { return type ? A() : B()}<br class="">}<br class=""><br class="">let a = P.factory(false) // &lt;- Not possible in Swift 2, factory() can<br class="">only be used on either A or B<br class=""><br class="">Regards<br class=""><br class="">Rasmus Friis Kjeldsen<br class=""><br class=""><br class=""><br class=""><br class=""></blockquote><br class="">'extension P' extends all types that conform to P. We could introduce a new<br class="">syntax for extending the protocol type, maybe:<br class=""><br class="">extension protocol&lt;P&gt; { ... }<br class=""><br class="">This might be an important part of fleshing out our support for protocol<br class="">existential types. It would offer a way for protocol types to conform to<br class="">their own protocols even when Self or associated types make that normally<br class="">impossible. <br class=""><br class="">-Joe <br class=""><br class=""><br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></body></html>