<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=""><div class="">The pitch was not warmly received. If you want to pick it up and run with it, go ahead. </div><div class=""><a href="https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a" class="">https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a</a></div><div class=""><br class=""></div><div class="">I have a running list of dead or deferred ideas here: <a href="https://gist.github.com/erica/9eae0d949297509ad86e" class="">https://gist.github.com/erica/9eae0d949297509ad86e</a></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">-- E</div><div class=""><br class=""></div><div><blockquote type="cite" class=""><div class="">On May 9, 2016, at 11:49 AM, Vladimir.S <<a href="mailto:svabox@gmail.com" class="">svabox@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Hi Erica, could you clarify, what is state of this proposal and your plans regarding it? I believe we certainly should make Swift more explicit regarding what methods in type are required by the conformed protocol and what methods are required(and which are 'optional') in protocol extensions.<br class=""><br class="">Right now there is a discussion regarding 'optional' keyword("Modify optional method semantics for swift"), and I remembered your proposal..<br class=""><br class="">Probably 'optional' keyword for non-required methods in extension instead of marking 'required' methods will looks better(as they are optional to the protocol itself), what do you think?<br class="">I.e.<br class=""><br class="">protocol A {<br class=""> func foo()<br class=""> func bar()<br class=""> func blort()<br class=""> func gar()<br class="">}<br class=""><br class="">extension A {<br class=""> //required func blort() {} // Correct, required by `A`<br class=""> //func womble() {} // Correct, new method in extension<br class=""> //func gar() {} // Incorrect: Compiler says: add `required` keyword..<br class=""><br class=""> func blort() {} // Correct, was introduced in `A`<br class=""> optional func womble() {} // Correct, new(optional) method in extension<br class=""> optional func gar() {} // Incorrect: Compiler says: remove `optional`..<br class="">}<br class=""><br class="">struct B: A {<br class=""> required func foo() {} // Correct<br class=""> required func far() {} // Near miss. Compiler: rename method or drop required keyword<br class=""> func bar() {} // Possible accidental name match. Compiler: rename method or add required keyword<br class=""><br class=""> func womble() {} // ?? how this method should be 'marked' ??<br class="">}<br class=""><br class="">(But personally I think one *overload* keyword will do the job in both cases - in extension and in type declaration)<br class=""><br class="">Regarding this "func womble()" questions.. I think we need *at least* compilation warning that *at the moment of compilation*, B.womble may(?) conflicts with extension of A.womble.<br class=""><br class="">Personaly I was not expecting to get the result of this code:<br class=""><br class="">protocol A {<br class=""> func a()<br class="">}<br class=""><br class="">extension A {<br class=""> func b() { print("(b) in A") }<br class="">}<br class=""><br class="">struct C : A {<br class=""> func a() {}<br class=""> func b() { print("(b) in C") }<br class="">}<br class=""><br class="">var c : A = C()<br class="">c.b() // (b) in A<br class=""><br class=""><br class=""><blockquote type="cite" class="">On 28.04.2016 19:53, Erica Sadun via swift-evolution wrote:<br class=""><blockquote type="cite" class="">Draft. Criticism and suggestions both welcome. -- E<br class=""><br class=""><br class=""> Requiring Proactive Overrides for Default Protocol Implementations<br class=""><br class=""> * Proposal: tbd<br class=""> * Author(s): Erica Sadun <<a href="http://github.com/erica" class="">http://github.com/erica</a>><br class=""> * Status: tbd<br class=""> * Review manager: tbd2<br class=""><br class=""><br class=""><br class=""><<a href="https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#introduction" class="">https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#introduction</a>>Introduction<br class=""><br class=""><br class="">This proposal enhances protocol implementation safety. It incorporates two<br class="">keywords that cooperate with compiler checks to limit "near miss"<br class="">implementation errors and accidental member overrides.<br class=""><br class="">/This proposal was discussed on the Swift Evolution list in the [Pitch]<br class="">Requiring proactive overrides for default protocol implementations.<br class=""><<a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/15496" class="">http://thread.gmane.org/gmane.comp.lang.swift.evolution/15496</a>> thread/<br class=""><br class=""><br class=""><br class=""><<a href="https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#motivation" class="">https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#motivation</a>>Motivation<br class=""><br class=""><br class="">The proposal introduces a mandatory |required| keyword that marks members<br class="">as fulfiling protocol requirements. This expansion reduces the risk of<br class="">near-miss implementations (for example, adding |thud(x:<br class="">Double)| when |thud(x: Float)|is required), provides in-line documentation<br class="">of why the member has been included, thereby enhancing the code-level<br class="">documentation at the implementation point, and supports compile-time checks<br class="">for protocol conformance.<br class=""><br class="">This proposal extends the |override| keyword to protocol conformance. The<br class="">Swift Programming Language describes the way subclass methods must override<br class="">implementations established in superclasses. /Methods on a subclass that<br class="">override the superclass’s implementation are marked with<br class="">*/|override|*/—overriding a method by accident, without override, is<br class="">detected by the compiler as an error. The compiler also detects methods<br class="">with override that don’t actually override any method in the superclass./<br class=""><br class="">Adding an |override| requirement expands this cautious approach to<br class="">protocols. Developers must override implementations inherited from protocol<br class="">extensions with the |override| keyword. And the compiler will flag uses<br class="">of |override| where member implementations do not, in fact, override an<br class="">existing implementation. The keyword prevents accidental overrides, where a<br class="">sensible member name conflicts with signatures established in the protocol<br class="">conformance and forces users to proactively select a version in favor of<br class="">existing protocol extensions.<br class=""><br class=""><br class=""><br class=""><<a href="https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#detail-design" class="">https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#detail-design</a>>Detail<br class=""><br class=""> Design<br class=""><br class=""> * The |override| keyword is extended to protocol inheritance, and when<br class=""> used prefers the overridden behavior to the default behavior.<br class=""> * Swift will prefer an overridden implementation in preference in reverse<br class=""> hierarchical order: type extensions take precedence over type<br class=""> declarations over protocol extensions over protocol declarations<br class=""> (assuming protocol declarations eventually adopt default<br class="">implementations).<br class=""> * The |required| keyword marks a member as satisfying a protocol<br class=""> requirement, whether in protocol extensions, type declarations, or type<br class=""> extensions.<br class=""><br class=""><br class=""><br class=""><<a href="https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#required-protocol-members" class="">https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#required-protocol-members</a>>Required<br class=""><br class=""> Protocol Members<br class=""><br class="">Protocol requirements are marked with |required| for compile-time checks of<br class="">intentional conformance.<br class=""><br class="">protocol A {<br class=""> func foo()<br class=""> func bar()<br class=""> func blort()<br class=""> func gar()<br class="">}<br class=""><br class="">extension A {<br class=""> required func blort() {} // Correct, required by `A`<br class=""> func womble() {} // Correct, new method in extension<br class=""> func gar() {} // Incorrect: Compiler says: add `required` keyword or<br class="">remove implementation<br class="">}<br class=""><br class="">struct B: A {<br class=""> required func foo() {} // Correct<br class=""> required func far() {} // Near miss. Compiler: rename method or drop<br class="">required keyword<br class=""> func bar() {} // Possible accidental name match. Compiler: rename<br class="">method or add required<br class="">keyword<br class="">}<br class=""><br class=""><br class=""><br class=""><<a href="https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#member-overrides" class="">https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#member-overrides</a>>Member<br class=""><br class=""> Overrides<br class=""><br class="">Overrides are marked with |override| to ensure intent.<br class=""><br class="">protocol A {<br class=""> func foo()<br class=""> func bar()<br class=""> func blort()<br class=""> func gar()<br class="">}<br class=""><br class="">extension A {<br class=""> required func foo() {} // correct<br class=""> func womble() {} // correct<br class="">}<br class=""><br class="">struct B: A {<br class=""> required func bar() {} // correct<br class=""> required func foo() {} // incorrect: Compiler says: add `override`<br class="">keyword or remove implementation<br class=""> func womble() {} // incorrect: Compiler says add `override` keyword<br class="">or remove<br class="">implementation. `required` is not needed as `womble` is not a required<br class="">protocol member.<br class="">}<br class=""><br class=""><br class=""><br class=""><<a href="https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#handling-changes" class="">https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#handling-changes</a>>Handling<br class=""><br class=""> Changes<br class=""><br class="">Default implementations can be added or removed at any time, as can type<br class="">conformance implementations:<br class=""><br class="">**Original** **Change** **Outcome**<br class="">Some member implemented in type Protocol adds that member Must add<br class="">`required` to type implementation or rename member to avoid conflict<br class="">Some member implemented in type, marked as `required` Protocol removes<br class="">that<br class="">member or it never existed Must remove `required` from type<br class="">implementation<br class="">Some member implemented in type, marked as `override` Protocol extension<br class="">removes that member or it never existed Must remove `override` from type<br class="">implementation<br class="">Some member implemented in typed, member not mentioned in protocol<br class="">Extension adds default version of member Type implementation must add<br class="">`override` keyword<br class="">`required` member implemented in type Default member added Must add<br class="">`override` or remove type implementation<br class="">`override required` member implemented in type Remove default<br class="">member Must<br class="">remove `override` in type implementation<br class="">`override required` member implemented in type Remove type member<br class="">implementation Default implementation now used<br class="">Type member uses `required` keyword Protocol removes requirement or never<br class="">had it Type implementation must remove `required` keyword<br class="">Protocol declares required member Extension implements default<br class="">implementation Extension must add `required` keyword, differentiating<br class="">default implementations from added behavior<br class="">Swift adds default implementations to protocols as well as extensions<br class="">Protocol adds default implementation Type implementation must use both<br class="">`required` and `override` keywords. Protocol extension must use `override`<br class="">keyword. Order of preference goes: overriden member, overriden extension,<br class="">protocol default implementation<br class=""><br class=""><br class=""><br class=""><<a href="https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#multiple-conformance-conflict" class="">https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#multiple-conformance-conflict</a>>Multiple<br class=""><br class=""> Conformance Conflict<br class=""><br class="">Consider the following situation. For the sake of future-proofing, this<br class="">example includes default protocol implementations although they do not yet<br class="">exist in Swift.<br class=""><br class="">protocol A { func foo() {...default...} }<br class="">protocol B { func foo() {...default...} }<br class="">extension A { override required func foo() {...A extension...} }<br class="">Type CType: A, B {}<br class=""><br class="">In this example, the compiler emits a warning that "CType cannot<br class="">unambiguously differentiate which version of |foo| to use<br class="">for |CType| instances". If the CType type were to be removed or either of<br class="">its conformances erased, there would be no compiler issues.<br class=""><br class="">To fix this scenario, CType must implement a version of foo that resolves<br class="">the conflict:<br class=""><br class="">Type CType: A, B { override required func foo() {<br class=""> // either<br class=""> A.foo(self)() // uses the A extension default implementation<br class=""> // or<br class=""> B.foo(self)() // uses the B protocol default implementation<br class=""> // or both, one after the other, etc.<br class="">}<br class=""><br class="">In this rewrite, |foo| is unambiguously referenced for |CType| instance<br class="">members.<br class=""><br class=""><br class=""><br class=""><<a href="https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#impact-on-existing-code" class="">https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#impact-on-existing-code</a>>Impact<br class=""><br class=""> on Existing Code<br class=""><br class="">These changes introduce mandates that do not exist in today's Swift code<br class="">and will require migration. The migrator (and compiler) must detect both<br class="">scenarios: that a member satisfies a protocol requirement and needs<br class="">the |required| keyword, and that a member overrides a default<br class="">implementation (in current Swift, only in extensions) and needs<br class="">the |override|keyword.<br class=""><br class="">In the degenerate case that protocol extensions provide two distinct<br class="">default implementations of the same member (whether required or not),<br class="">the |override| version should always be preferred. When<br class="">multiple |override| versions exist, the compiler should emit a warning<br class="">about ambiguous resolution.<br class=""><br class="">Using type currying, e.g. |A.foo(self)| should always resolve using the<br class="">rules enumerated earlier in this proposal, moving from type extensions to<br class="">types to protocol extension to protocols.<br class=""><br class=""><br class=""><br class=""><<a href="https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#alternatives-considered" class="">https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#alternatives-considered</a>>Alternatives<br class=""><br class=""> Considered<br class=""><br class="">Not at this time.<br class=""><br class=""><br class=""><br class=""><<a href="https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#acknowledgements-and-thanks" class="">https://gist.github.com/erica/fc66e6f6335750d737e5512797e8284a#acknowledgements-and-thanks</a>>Acknowledgements<br class=""><br class=""> and Thanks<br class=""><br class="">Thanks, Doug Gregor, Jordan Rose, and Joe Groff<br class=""><br class=""><br class=""><br class=""><br class=""><blockquote type="cite" class="">On Apr 27, 2016, at 6:07 PM, Douglas Gregor <<a href="mailto:dgregor@apple.com" class="">dgregor@apple.com</a><br class=""><<a href="mailto:dgregor@apple.com" class="">mailto:dgregor@apple.com</a>>> wrote:<br class=""></blockquote><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="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""><br class=""></blockquote></blockquote></div></div></blockquote></div><br class=""></body></html>