[swift-evolution] Mark protocol methods with their protocol
Vladimir.S
svabox at gmail.com
Tue Sep 20 10:13:35 CDT 2016
> extension P {
> implement func foo() -> [String : String] { return [:] }
> }
Yes, it seems like we need `implement` (or `override` as another
suggestion) in protocol extension also just for the same reasons - be clear
about our intention regarding implementing the requirement, to show that
this func *depends* on the previous definition of P protocol and to avoid
possible mistakes related to protocol conformance.
On 20.09.2016 17:38, Charles Srstka wrote:
>> On Sep 20, 2016, at 8:17 AM, Vladimir.S via swift-evolution
>> <swift-evolution at swift.org <mailto: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
>
More information about the swift-evolution
mailing list