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