[swift-evolution] Mark protocol methods with their protocol

Charles Srstka cocoadev at charlessoft.com
Tue Sep 20 09:38:39 CDT 2016


> On Sep 20, 2016, at 8:17 AM, Vladimir.S via swift-evolution <swift-evolution at swift.org> wrote:
> 
> On 20.09.2016 3:03, Xiaodi Wu via swift-evolution wrote:
>> I definitely think Vladimir's suggestion is a great starting point, IMO.
>> 
>> However, I think it could be improved in one key respect where previous
>> proposals using `override` are superior. Namely, the proposed `implement`
>> keyword adds no additional safety when a type implements a protocol
>> requirement that doesn't have a default implementation. This is because, if
> 
> Yes, *at the moment of writing* the type's code there could be no default implementation for protocol requirement. But, *at the moment of compilation* such default implementation could appear.
> 
> Let's discuss such scenario in case we'll take your suggestion:
> 
> You got SomeClass.swift file, 3rd party file you don't want to change or changes are not allowed. Content:
> 
> public protocol SomeProtocol {
> 	func foo()
> }
> 
> public class SomeClass : SomeProtocol {
> 	func foo() {...} // no default implementation *at the moment of writing*, no need in `overload`
> }
> 
> Now, you adds SomeClass.swift file to your project and in some *other* file you write:
> 
> extension SomeProtocol {
> 	func foo() {...}
> }
> 
> As you see, you don't control the SomeClass.swift but you suggest in this case SomeClass.foo() should be defined with `override`.
> 
> With 'implement' SomeClass.foo() will be marked initially and will save us if protocol's requirement PLUS default implementation changed.

Requiring the ‘implement’ keyword can help us even if no default implementation is involved. Consider:

protocol P {
	func foo() -> [String : Any]
}

struct S : P {
	func foo() -> [String : String] { return [:] }
}

We will get an error here that S does not conform to P. However, this is not the correct error, since S in fact *tries* to conform to P, but it has a mistake in a method signature. This misleads us as to the true nature of the problem, and if S has enough members in it that we fail to spot the existing foo(), we might solve the problem by reimplementing foo(), and leaving the original foo() as dangling dead code. Having an ‘implement’ keyword on the existing foo() function would change the compiler error to let us know that we have an existing foo() that is incorrectly declared.

In addition, ‘implement’ can help us when the declaration in question *is* the default implementation:

protocol P {
	func foo() -> [String : Any]
}

extension P {
	implement func foo() -> [String : String] { return [:] }
}

Here we will get an error with the proposed ‘implement’ keyword, because foo() does not have a signature matching anything in the protocol, whereas without ‘implement’ we would happily and silently generate a useless dangling function that would never be used, and then pass the buck to the concrete type that implements P:

protocol P {
	func foo() -> [String : Any]
}

extension P {
	func foo() -> [String : String] { return [:] } // The error is here:
}

struct S : P {} // But it gets reported here.

Charles

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160920/536c332e/attachment.html>


More information about the swift-evolution mailing list