<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>