[swift-evolution] Keyword for protocol conformance

Charles Srstka cocoadev at charlessoft.com
Fri Aug 26 05:08:54 CDT 2016


> On Aug 26, 2016, at 4:34 AM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
> 
> On Fri, Aug 26, 2016 at 4:24 AM, Charles Srstka <cocoadev at charlessoft.com <mailto:cocoadev at charlessoft.com>> wrote:
>> On Aug 26, 2016, at 4:02 AM, Xiaodi Wu <xiaodi.wu at gmail.com <mailto:xiaodi.wu at gmail.com>> wrote:
>> 
>> That is not exactly what Brent was speaking of. We are talking about this scenario:
>> 
>> File A:
>> 
>> ```
>> internal struct S {
>>   func foo() { }
>> }
>> ```
>> 
>> File B:
>> 
>> ```
>> private protocol P {
>>   func foo()
>> }
>> 
>> extension P {
>>   func foo() { }
>> }
>> 
>> // With your proposal, I can't write the following line:
>> extension S : P { }
>> // In file A, S.foo() isn't overriding anything, so I can't add `override`
>> // But in file B, S can't conform to P,
>> // because S.foo() isn't overriding P.foo() without `override` in file A
> 
> First of all, I cannot take credit for the proposal, as the thread was started by David, not me, so if the proposal is anyone’s, it’s his. With that said, what he proposes is:
> 
>> On Aug 22, 2016, at 4:30 PM, David Cordero via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>> Proposal:
>> Adding a keyword to the methods conforming protocols. As an example please check the following piece of code which uses the keyword `conform` to explicitly indicate that `myMethod` is a method conforming a protocol.
> 
> 
> The wording here is that the keyword is needed for methods conforming to protocols. My reading of that is that:
> 
> File A:
> 
> protocol P {
> 	func foo()
> }
> 
> struct S: P {
> 	conform func foo() {
> 		// I am declared as conforming to P, so in adding this method I am doing so to conform to P. Thus, I need the keyword.
> 	}
> }
> 
> - - whereas: - -
> 
> File A:
> 
> struct S {
> 	func foo() {
> 		// I am not declared as conforming to any protocol; I just think that being able to foo is an ability that I need to have.
> 	}
> }
> 
> File B:
> 
> private protocol P {
> 	func foo()
> }
> 
> extension S: P {
> 	// The area of contention.
> }
> 
> - - - - - -
> 
> The proposal doesn’t really mention what to do here, so we can argue a bit about it. There are multiple viewpoints one could take on this. A few could be:
> 
> 1. The extension should get some kind of keyword, “retro” or “@retro” or something better-sounding that someone smarter than I comes up with.
> 
> 2. The extension is unmarked, but declares foo() inside it with some sort of annotation to indicate that it represents a method that already exists.
> 
> 3. Just leave the extension exactly as written, since it’s not declaring any methods, and thus doesn’t have to indicate what those nonexistent method declarations conform to.
> 
> I began this discussion leaning toward #1, but now I’m starting to consider #3, since the purpose of the keyword is to declare one’s intentions. The intentions of an empty extension that does nothing but conform to a protocol is actually quite clear; the methods have to be already declared somewhere else, or it makes no sense. At any rate, the “problem” in your scenario is entirely confined to File B, so if any annotations are necessary, that is where they belong. File A does not know about the protocol, it does not know that it is conforming to the protocol, and indeed, the protocol is none of File A’s business. So since File A is not intending to conform to the protocol, File A does not have to declare its intent to conform to the protocol. If we require that, it’s all in File B’s court.
> 
> As I said, this discussion has already happened several times. I'm literally just repeating what people said eight months ago, six months ago, and four months ago. There's not a good answer to this and perhaps several other issues, which is why I don't see a way forward for the proposal. After all, I was the one proposing the same idea last winter, so I've had a few months to think about it.
> 
> If option (3) were allowed, then no keyword could ever be mandatory; it's always possible to refactor so that a conformance declaration is an empty extension. So we're back at an optional keyword, which has its own problems. This kind of thinking is how I've come to the conclusion that the status quo, with better diagnostics, is the least bad solution.


Two responses to that thought:

1) In general, I look at these things under the assumption that most developers are not going to be making efforts to deliberately break the system, and not to try to expend excessive amounts of time in preventing them from doing so. Because really, just about *anything* can be worked around. I can work around the “override” keyword and override things without it, but that doesn’t mean that I think we should remove the “override” keyword. For that matter, just about *everything* in Objective-C was workaroundable, and usually rather trivially at that, but that didn’t make us all go back to typing everything as ‘id’ just because the explicit types could be spoofed.

2) Even if you disagree with everything I just said, that’s just as much an argument for option #1 as for the status quo.

Charles

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160826/145d9ec4/attachment.html>


More information about the swift-evolution mailing list