[swift-evolution] Mark protocol methods with their protocol

Maximilian Hünenberger m.huenenberger at me.com
Mon Sep 26 00:06:19 CDT 2016


> Am 23.09.2016 um 12:47 schrieb Vladimir.S <svabox at gmail.com>:
> 
>> On 23.09.2016 11:05, Maximilian Hünenberger wrote:
>> I'd also say that one or two keywords are superior than the protocol naming
>> approach in terms of implementation simplicity (for the core team).
>> 
>> My suggestions:
>> 
>> Either "conform" or "implement" should be a required keyword for all
>> properties/functions which implement a protocol (also in protocol extensions)
>> 
> 
>> "override" should be used if a default implementation or a member of a
>> superclass is overridden.
> 
> Maximilian, again, you *do not know* if the conformed protocol, that has no default implementations *at the moment of your code writing* will or will not have default implementations at the *moment of compilation*.
> Consider this scenario:
> 
> Step 1. You got 3rd party source file for your project, and you don't want/have no rights to change it, probably it is shared source used also in other projects, that code contains:
> 
> protocol A { func foo() }
> 
> class B : A {
>    conform func foo() {...}
> }
> 
> all is OK with this code, no default implementation, B.foo marked with `conform`.
> 
> Step 2. In your project in some of your files you decided to add default implementation of protocol A:
> 
> extension A {
>    implement func foo() {...}
> }
> 
> Now, your project will not compile - B.foo() must me marked with 'override' as protocol `A` has default implementation of foo().
> If you change `conform` to `override` in 3rd party source file, it will not compile in some other project where no default implementation defined for `A` protocol.
> 
> That is *why* I believe the `override` as requirement as marker for protocol implementation method/prop is the best solution. See, in case `override` will be required, the initial source file will be like this:
> 
> protocol A { func foo() }
> 
> class B : A {
>    override func foo() {...} // implementation
> }
> 
> and it will compile ok : if A has default implementation and if A has no default implementation.
> 
> So, after you added default implementation in your project - no changes should be made to that 3rd party source file.
> 
> 

In case of my suggestion this is an easy fix: `override` is not required if it overrides a member of an extension in another module.

My basic idea is to distinguish between implementation and (true) overriding (of other members. Do you agree?

Consider this:

protocol A1 {
    func foo()
}

extension A1 {
    implement func foo() {}
}

protocol A2: A1 {
    override func foo() {}
}

In this case you know that `foo` in extension A1 does not override any other method.

Best regards
Maximilian

>> 
>> If you are overriding a default implementation of a protocol "conform" /
>> "implement" is also required.
>> 
>> // Retroactive conformance (old behavior) but only in extensions
>> extension Foo: @retroactive Baz {
>>    // only some members of Baz are implemented here (they need the keywords)
>>    // the other members outside the extension don't need any additional
>> keywords
>>    // note: you can use "@retroactive" and "conform" in conjunction
>> }
>> 
>> 
>> *Future directions:*
>> "conform(ProtocolName)" / "override(ProtocolName)" can be used to disambiguate.
>> 
>> // reducing boilerplate
>> extension Foo: conform Bar {
>>    // These declarations can only implement Bar and don't need the
>> "conform" keyword
>> }
>> 
>> *Final question:*
>> Should we also require a marker for implemented protocol members in the
>> interface?:
>> 
>> protocol Foo {
>>    defaulted func foo()
>> }
>> extension Foo {
>>    implement func foo()
>> }
>> 
>> 
>> Best regards
>> Maximilian

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160926/6492b045/attachment.html>


More information about the swift-evolution mailing list