Keyword for protocol conformance

~Robert Widmann

2016/08/23 20:52、Charles Srstka <cocoadev@charlessoft.com> のメッセージ:

2016/08/23 15:29、Charles Srstka <cocoadev@charlessoft.com> のメッセージ:

2016/08/22 14:30、David Cordero via swift-evolution <swift-evolution@swift.org> のメッセージ:

The problem:
At the moment, looking at the code of a class or a struct implementing a protocol, it is hard to know what methods are actually implementing the protocol and what other methods are just part of the code of the class or struct.

That seems like a feature, not a bug. Why should I as an author care whether a method contributes to a protocol conformance or not if the compiler can tell me that kind of information itself?

Being able to reason about your code, what it does, and what it’s for is undesirable?

That's not an answer to the question I asked. Why is this significant enough to warrant an entire keyword? The clutter of a whole keyword that does nothing but wait for a developer to make a source-compatible binary-breaking change to an interface does not seem worth it. Maybe you can convince me otherwise.

Same reason overriding a class method warrants a keyword. It expresses the purpose more clearly, and allows the compiler to catch mistakes for us.

That's just it: The class of mistakes one can make by not being explicit about overrides is significantly more dangerous than the class of mistakes caused by dead code leftover from trimming protocols.

protocol MyProtocol {
    func myMethod() -> String
}

class MyClass: MyProtocol {

    conform func myMethod() -> String {
        return "Yuhuuu,I am conforming \\o//"
    }

    func whatever() {
        print("I am a boring method and I don't conform anything")
    }
}

It would be something similar to the current keyword `override` but for protocols.

Apart from improving code readability, It would allow the detection, in compilation time, of errors due to code evolution. For example redundant methods that no longer conform anything once the requirement is removed from the protocol for whatever reason.

If you make a breaking change to a protocol like this, you should have gone through a deprecation cycle to indicate to your clients the appropriate changes you're going to make to the protocol. This aspect of the change seems to if not encourage, highlight, bad behavior.

What if it’s your own code and all the callers are internal? What if you’re still developing the protocol and haven’t released the API interface yet?

Then your concerns are local enough that you know where all implementations of the protocol lie and whether they require deletion or not. The point about deprecation cycles still stands in all the cases you mention. Just because the interface is private doesn't mean you can't take responsibility for keeping it as clean as you can.

Charles

tl;dr It seems like all of this can be subsumed by us warning about dead code.

Did you look at my examples earlier in the thread? Neither of those would be caught by warning about dead code.

The example involving the default implementation is most compelling, but it indicates that your proposed solution should focus on the protocol extension and not the implementing declaration. Perhaps reusing one of our existing keywords can help here

protocol P {
  func foo() {}
}

extension P {
  default func foo() {}
}

struct S: P {}

Of course, this change would be potentially source-breaking either way - I don't like the sound of an "optional keyword".

Either way, we can all agree we need better diagnostics around these cases.

···

On Aug 23, 2016, at 10:34 PM, Robert Widmann <devteam.codafi@gmail.com> wrote:

On Aug 23, 2016, at 2:33 PM, Robert Widmann via swift-evolution <swift-evolution@swift.org> wrote:

Charles

2016/08/23 20:52、Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> のメッセージ:

2016/08/23 15:29、Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> のメッセージ:

2016/08/22 14:30、David Cordero via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> のメッセージ:

The problem:
At the moment, looking at the code of a class or a struct implementing a protocol, it is hard to know what methods are actually implementing the protocol and what other methods are just part of the code of the class or struct.

That seems like a feature, not a bug. Why should I as an author care whether a method contributes to a protocol conformance or not if the compiler can tell me that kind of information itself?

Being able to reason about your code, what it does, and what it’s for is undesirable?

That's not an answer to the question I asked. Why is this significant enough to warrant an entire keyword? The clutter of a whole keyword that does nothing but wait for a developer to make a source-compatible binary-breaking change to an interface does not seem worth it. Maybe you can convince me otherwise.

Same reason overriding a class method warrants a keyword. It expresses the purpose more clearly, and allows the compiler to catch mistakes for us.

That's just it: The class of mistakes one can make by not being explicit about overrides is significantly more dangerous than the class of mistakes caused by dead code leftover from trimming protocols.

I am in the middle of a large refactor of code that was originally Objective-C and then Swift written like Objective-C, to more idiomatic protocol-oriented Swift. I am finding that in Swift’s POP idiom, protocols with overrides are serving very nearly the same purpose that overrides were serving in the old design; hence, I don’t really think either is more or less dangerous than the other.

protocol MyProtocol {
    func myMethod() -> String
}

class MyClass: MyProtocol {

    conform func myMethod() -> String {
        return "Yuhuuu,I am conforming \\o// <smb://o//>"
    }

    func whatever() {
        print("I am a boring method and I don't conform anything")
    }
}

It would be something similar to the current keyword `override` but for protocols.

Apart from improving code readability, It would allow the detection, in compilation time, of errors due to code evolution. For example redundant methods that no longer conform anything once the requirement is removed from the protocol for whatever reason.

If you make a breaking change to a protocol like this, you should have gone through a deprecation cycle to indicate to your clients the appropriate changes you're going to make to the protocol. This aspect of the change seems to if not encourage, highlight, bad behavior.

What if it’s your own code and all the callers are internal? What if you’re still developing the protocol and haven’t released the API interface yet?

Then your concerns are local enough that you know where all implementations of the protocol lie and whether they require deletion or not. The point about deprecation cycles still stands in all the cases you mention. Just because the interface is private doesn't mean you can't take responsibility for keeping it as clean as you can.

Charles

tl;dr It seems like all of this can be subsumed by us warning about dead code.

Did you look at my examples earlier in the thread? Neither of those would be caught by warning about dead code.

The example involving the default implementation is most compelling, but it indicates that your proposed solution should focus on the protocol extension and not the implementing declaration. Perhaps reusing one of our existing keywords can help here

protocol P {
  func foo() {}
}

extension P {
  default func foo() {}
}

struct S: P {}

Of course, this change would be potentially source-breaking either way - I don't like the sound of an "optional keyword”.

I can come up with a similar example without the mistake being in the extension, though:

protocol P {
  func foo() {}
}

extension P {
  func foo() { print(“Default Behavior”) }
}

struct S: P {
  func foo() { print(“Specific Behavior”) }
}

So far, so good. But now I realize that the original protocol needs an argument:

protocol P {
  func foo(bar: String) {}
}

extension P {
  func foo(bar: String) { print(“Default Behavior; bar is \(bar)”) }
}

struct S: P {
  func foo() { print(“Specific Behavior”) } // Whoops, forgot to update this method, and now it won’t get called—and we of course won’t see the carnage until runtime.
}

Either way, we can all agree we need better diagnostics around these cases.

No doubt.

Charles

···

On Aug 24, 2016, at 1:20 AM, Robert Widmann <devteam.codafi@gmail.com> wrote:

On Aug 23, 2016, at 10:34 PM, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:

On Aug 23, 2016, at 2:33 PM, Robert Widmann via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Requiring "override" when anything overrides a method defined in a protocol extension should be added - structure and enumerated included, of course.

Protocol extensions added inheritance to structs and enums and this should be made explicit.

···

Sent from my iPad

On Aug 24, 2016, at 12:55 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:

On Aug 24, 2016, at 1:20 AM, Robert Widmann <devteam.codafi@gmail.com> wrote:
2016/08/23 20:52、Charles Srstka <cocoadev@charlessoft.com> のメッセージ:

On Aug 23, 2016, at 10:34 PM, Robert Widmann <devteam.codafi@gmail.com> wrote:

2016/08/23 15:29、Charles Srstka <cocoadev@charlessoft.com> のメッセージ:

On Aug 23, 2016, at 2:33 PM, Robert Widmann via swift-evolution <swift-evolution@swift.org> wrote:

2016/08/22 14:30、David Cordero via swift-evolution <swift-evolution@swift.org> のメッセージ:

The problem:
At the moment, looking at the code of a class or a struct implementing a protocol, it is hard to know what methods are actually implementing the protocol and what other methods are just part of the code of the class or struct.

That seems like a feature, not a bug. Why should I as an author care whether a method contributes to a protocol conformance or not if the compiler can tell me that kind of information itself?

Being able to reason about your code, what it does, and what it’s for is undesirable?

That's not an answer to the question I asked. Why is this significant enough to warrant an entire keyword? The clutter of a whole keyword that does nothing but wait for a developer to make a source-compatible binary-breaking change to an interface does not seem worth it. Maybe you can convince me otherwise.

Same reason overriding a class method warrants a keyword. It expresses the purpose more clearly, and allows the compiler to catch mistakes for us.

That's just it: The class of mistakes one can make by not being explicit about overrides is significantly more dangerous than the class of mistakes caused by dead code leftover from trimming protocols.

I am in the middle of a large refactor of code that was originally Objective-C and then Swift written like Objective-C, to more idiomatic protocol-oriented Swift. I am finding that in Swift’s POP idiom, protocols with overrides are serving very nearly the same purpose that overrides were serving in the old design; hence, I don’t really think either is more or less dangerous than the other.

protocol MyProtocol {
    func myMethod() -> String
}

class MyClass: MyProtocol {

    conform func myMethod() -> String {
        return "Yuhuuu,I am conforming \\o//"
    }

    func whatever() {
        print("I am a boring method and I don't conform anything")
    }
}

It would be something similar to the current keyword `override` but for protocols.

Apart from improving code readability, It would allow the detection, in compilation time, of errors due to code evolution. For example redundant methods that no longer conform anything once the requirement is removed from the protocol for whatever reason.

If you make a breaking change to a protocol like this, you should have gone through a deprecation cycle to indicate to your clients the appropriate changes you're going to make to the protocol. This aspect of the change seems to if not encourage, highlight, bad behavior.

What if it’s your own code and all the callers are internal? What if you’re still developing the protocol and haven’t released the API interface yet?

Then your concerns are local enough that you know where all implementations of the protocol lie and whether they require deletion or not. The point about deprecation cycles still stands in all the cases you mention. Just because the interface is private doesn't mean you can't take responsibility for keeping it as clean as you can.

Charles

tl;dr It seems like all of this can be subsumed by us warning about dead code.

Did you look at my examples earlier in the thread? Neither of those would be caught by warning about dead code.

The example involving the default implementation is most compelling, but it indicates that your proposed solution should focus on the protocol extension and not the implementing declaration. Perhaps reusing one of our existing keywords can help here

protocol P {
  func foo() {}
}

extension P {
  default func foo() {}
}

struct S: P {}

Of course, this change would be potentially source-breaking either way - I don't like the sound of an "optional keyword”.

I can come up with a similar example without the mistake being in the extension, though:

protocol P {
  func foo() {}
}

extension P {
  func foo() { print(“Default Behavior”) }
}

struct S: P {
  func foo() { print(“Specific Behavior”) }
}

So far, so good. But now I realize that the original protocol needs an argument:

protocol P {
  func foo(bar: String) {}
}

extension P {
  func foo(bar: String) { print(“Default Behavior; bar is \(bar)”) }
}

struct S: P {
  func foo() { print(“Specific Behavior”) } // Whoops, forgot to update this method, and now it won’t get called—and we of course won’t see the carnage until runtime.
}

Either way, we can all agree we need better diagnostics around these cases.

No doubt.

Charles

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

If we really want to be overkill, we could use `required` for implementing an un-defaulted protocol requirement, `override` for implementing a defaulted protocol requirement, and `default` for implementing a protocol requirement in a protocol extension.

I think this might be more verbose than necessary, but I think it is at least worth exploring some subset of those keywords. They all reuse existing ones too, which is mostly a plus.

The biggest benefit I see from these is confidence that what you wrote satisfies your expectations. Just like `try` is required to document at the call-site that a method throws and like argument labels are required to document at the call-site the usage of each parameter, it's reasonable to require these keywords to document these expectations at the implementation-site. If you forget them, the compiler can easily remind you.

Requiring `override` and/or `required` would make it clear that you're actually implementing the protocol. It's too easily to make a typo and define a completely unrelated method. If the requirement is defaulted, you would never know until runtime weirdness. These keywords make protocol conformance less stringily typed.

I'm +1 on this idea in some form (but not necessarily what I suggested).

···

On Aug 24, 2016, at 10:13 AM, Christopher Kornher via swift-evolution <swift-evolution@swift.org> wrote:

Requiring "override" when anything overrides a method defined in a protocol extension should be added - structure and enumerated included, of course.

Protocol extensions added inheritance to structs and enums and this should be made explicit.

Sent from my iPad

On Aug 24, 2016, at 12:55 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Aug 24, 2016, at 1:20 AM, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:
2016/08/23 20:52、Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> のメッセージ:

On Aug 23, 2016, at 10:34 PM, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:

2016/08/23 15:29、Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> のメッセージ:

On Aug 23, 2016, at 2:33 PM, Robert Widmann via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

2016/08/22 14:30、David Cordero via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> のメッセージ:

The problem:
At the moment, looking at the code of a class or a struct implementing a protocol, it is hard to know what methods are actually implementing the protocol and what other methods are just part of the code of the class or struct.

That seems like a feature, not a bug. Why should I as an author care whether a method contributes to a protocol conformance or not if the compiler can tell me that kind of information itself?

Being able to reason about your code, what it does, and what it’s for is undesirable?

That's not an answer to the question I asked. Why is this significant enough to warrant an entire keyword? The clutter of a whole keyword that does nothing but wait for a developer to make a source-compatible binary-breaking change to an interface does not seem worth it. Maybe you can convince me otherwise.

Same reason overriding a class method warrants a keyword. It expresses the purpose more clearly, and allows the compiler to catch mistakes for us.

That's just it: The class of mistakes one can make by not being explicit about overrides is significantly more dangerous than the class of mistakes caused by dead code leftover from trimming protocols.

I am in the middle of a large refactor of code that was originally Objective-C and then Swift written like Objective-C, to more idiomatic protocol-oriented Swift. I am finding that in Swift’s POP idiom, protocols with overrides are serving very nearly the same purpose that overrides were serving in the old design; hence, I don’t really think either is more or less dangerous than the other.

protocol MyProtocol {
    func myMethod() -> String
}

class MyClass: MyProtocol {

    conform func myMethod() -> String {
        return "Yuhuuu,I am conforming \\o// <smb://o//>"
    }

    func whatever() {
        print("I am a boring method and I don't conform anything")
    }
}

It would be something similar to the current keyword `override` but for protocols.

Apart from improving code readability, It would allow the detection, in compilation time, of errors due to code evolution. For example redundant methods that no longer conform anything once the requirement is removed from the protocol for whatever reason.

If you make a breaking change to a protocol like this, you should have gone through a deprecation cycle to indicate to your clients the appropriate changes you're going to make to the protocol. This aspect of the change seems to if not encourage, highlight, bad behavior.

What if it’s your own code and all the callers are internal? What if you’re still developing the protocol and haven’t released the API interface yet?

Then your concerns are local enough that you know where all implementations of the protocol lie and whether they require deletion or not. The point about deprecation cycles still stands in all the cases you mention. Just because the interface is private doesn't mean you can't take responsibility for keeping it as clean as you can.

Charles

tl;dr It seems like all of this can be subsumed by us warning about dead code.

Did you look at my examples earlier in the thread? Neither of those would be caught by warning about dead code.

The example involving the default implementation is most compelling, but it indicates that your proposed solution should focus on the protocol extension and not the implementing declaration. Perhaps reusing one of our existing keywords can help here

protocol P {
  func foo() {}
}

extension P {
  default func foo() {}
}

struct S: P {}

Of course, this change would be potentially source-breaking either way - I don't like the sound of an "optional keyword”.

I can come up with a similar example without the mistake being in the extension, though:

protocol P {
  func foo() {}
}

extension P {
  func foo() { print(“Default Behavior”) }
}

struct S: P {
  func foo() { print(“Specific Behavior”) }
}

So far, so good. But now I realize that the original protocol needs an argument:

protocol P {
  func foo(bar: String) {}
}

extension P {
  func foo(bar: String) { print(“Default Behavior; bar is \(bar)”) }
}

struct S: P {
  func foo() { print(“Specific Behavior”) } // Whoops, forgot to update this method, and now it won’t get called—and we of course won’t see the carnage until runtime.
}

Either way, we can all agree we need better diagnostics around these cases.

No doubt.

Charles

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I hope that my brief email wasn’t the final word on this :(

Does anyone think that a proposal to require “override” for overrides of protocol extension methods and variables (?) would be worth exploring?

This would address a number of the issues raised in this thread, but not all.

My intention is not to derail this thread, and I believe that the original topic of this thread, explicit protocol conformance, is worth exploring. I respond here because of these topics are strongly related. I will start a new thread, if there is interest.

It is possible that tooling could address the remaining issues with overrides. JetBrains products, for example, provide navigable icons to overridden methods. There is no reason that Xcode and other tools could not automatically insert indicators like:

class MyClass: MyProtocol {

	< conforms >
	func myMethod() -> String {
        	return “..."
   	}

class MyClass2: MyProtocol1, MyProtocol2 {

	< conforms MyProtocol2 >
	func myMethod() -> String {
        	return “..."
    	}

Of course, there is no reason that tooling can’t replace “override” completely:

class MyClass: MyOtherClass, MyProtocol1, MyProtocol2 {

	< conforms MyProtocol2 >
	< overrides TheParentClassOfMyOtherClass>
	func myMethod() -> String {
        	return “..."
    	}

Replace "<…>” with the navigable graphic of your choice and assume that user preferences would exist to show/hide these indicators.

···

On Aug 24, 2016, at 11:13 AM, Christopher Kornher via swift-evolution <swift-evolution@swift.org> wrote:

Requiring "override" when anything overrides a method defined in a protocol extension should be added - structure and enumerated included, of course.

Protocol extensions added inheritance to structs and enums and this should be made explicit.

Sent from my iPad

On Aug 24, 2016, at 12:55 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Aug 24, 2016, at 1:20 AM, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:
2016/08/23 20:52、Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> のメッセージ:

On Aug 23, 2016, at 10:34 PM, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:

2016/08/23 15:29、Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> のメッセージ:

On Aug 23, 2016, at 2:33 PM, Robert Widmann via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

2016/08/22 14:30、David Cordero via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> のメッセージ:

The problem:
At the moment, looking at the code of a class or a struct implementing a protocol, it is hard to know what methods are actually implementing the protocol and what other methods are just part of the code of the class or struct.

That seems like a feature, not a bug. Why should I as an author care whether a method contributes to a protocol conformance or not if the compiler can tell me that kind of information itself?

Being able to reason about your code, what it does, and what it’s for is undesirable?

That's not an answer to the question I asked. Why is this significant enough to warrant an entire keyword? The clutter of a whole keyword that does nothing but wait for a developer to make a source-compatible binary-breaking change to an interface does not seem worth it. Maybe you can convince me otherwise.

Same reason overriding a class method warrants a keyword. It expresses the purpose more clearly, and allows the compiler to catch mistakes for us.

That's just it: The class of mistakes one can make by not being explicit about overrides is significantly more dangerous than the class of mistakes caused by dead code leftover from trimming protocols.

I am in the middle of a large refactor of code that was originally Objective-C and then Swift written like Objective-C, to more idiomatic protocol-oriented Swift. I am finding that in Swift’s POP idiom, protocols with overrides are serving very nearly the same purpose that overrides were serving in the old design; hence, I don’t really think either is more or less dangerous than the other.

protocol MyProtocol {
    func myMethod() -> String
}

class MyClass: MyProtocol {

    conform func myMethod() -> String {
        return "Yuhuuu,I am conforming \\o// <smb://o//>"
    }

    func whatever() {
        print("I am a boring method and I don't conform anything")
    }
}

It would be something similar to the current keyword `override` but for protocols.

Apart from improving code readability, It would allow the detection, in compilation time, of errors due to code evolution. For example redundant methods that no longer conform anything once the requirement is removed from the protocol for whatever reason.

If you make a breaking change to a protocol like this, you should have gone through a deprecation cycle to indicate to your clients the appropriate changes you're going to make to the protocol. This aspect of the change seems to if not encourage, highlight, bad behavior.

What if it’s your own code and all the callers are internal? What if you’re still developing the protocol and haven’t released the API interface yet?

Then your concerns are local enough that you know where all implementations of the protocol lie and whether they require deletion or not. The point about deprecation cycles still stands in all the cases you mention. Just because the interface is private doesn't mean you can't take responsibility for keeping it as clean as you can.

Charles

tl;dr It seems like all of this can be subsumed by us warning about dead code.

Did you look at my examples earlier in the thread? Neither of those would be caught by warning about dead code.

The example involving the default implementation is most compelling, but it indicates that your proposed solution should focus on the protocol extension and not the implementing declaration. Perhaps reusing one of our existing keywords can help here

protocol P {
  func foo() {}
}

extension P {
  default func foo() {}
}

struct S: P {}

Of course, this change would be potentially source-breaking either way - I don't like the sound of an "optional keyword”.

I can come up with a similar example without the mistake being in the extension, though:

protocol P {
  func foo() {}
}

extension P {
  func foo() { print(“Default Behavior”) }
}

struct S: P {
  func foo() { print(“Specific Behavior”) }
}

So far, so good. But now I realize that the original protocol needs an argument:

protocol P {
  func foo(bar: String) {}
}

extension P {
  func foo(bar: String) { print(“Default Behavior; bar is \(bar)”) }
}

struct S: P {
  func foo() { print(“Specific Behavior”) } // Whoops, forgot to update this method, and now it won’t get called—and we of course won’t see the carnage until runtime.
}

Either way, we can all agree we need better diagnostics around these cases.

No doubt.

Charles

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I hope that my brief email wasn’t the final word on this :(

Does anyone think that a proposal to require “override” for overrides of protocol extension methods and variables (?) would be worth exploring?

This would address a number of the issues raised in this thread, but not all.

My intention is not to derail this thread, and I believe that the original topic of this thread, explicit protocol conformance, is worth exploring. I respond here because of these topics are strongly related. I will start a new thread, if there is interest.

It is possible that tooling could address the remaining issues with overrides. JetBrains products, for example, provide navigable icons to overridden methods. There is no reason that Xcode and other tools could not automatically insert indicators like:

class MyClass: MyProtocol {

	< conforms >
	func myMethod() -> String {
        	return “..."
   	}

class MyClass2: MyProtocol1, MyProtocol2 {

	< conforms MyProtocol2 >
	func myMethod() -> String {
        	return “..."
    	}

Of course, there is no reason that tooling can’t replace “override” completely:

class MyClass: MyOtherClass, MyProtocol1, MyProtocol2 {

	< conforms MyProtocol2 >
	< overrides TheParentClassOfMyOtherClass>
	func myMethod() -> String {
        	return “..."
    	}

Replace "<…>” with the navigable graphic of your choice and assume that user preferences would exist to show/hide these indicators.

My cut and paste error left out this part:

The roles of language and tooling in making code understandable is largely a matter of opinion. I personally like the current use of “override” since overriding is a common cause of serious programming errors and a mechanism for protecting against them should be built into the language and now, extended to overrides of protocol extensions.

It is interesting that adding “override” to structs and enums would help to open the door to true inheritance (not polymorphism) for structs and possibly even enums, if anyone knows of a use for that. This is a feature that I could have used on a few projects, but there are far more important features in the queue, and that discussion should probably wait until after Swift 4, if it happens at all.

- Chris K

···

On Aug 25, 2016, at 4:32 PM, Christopher Kornher <ckornher@me.com> wrote:

On Aug 24, 2016, at 11:13 AM, Christopher Kornher via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Requiring "override" when anything overrides a method defined in a protocol extension should be added - structure and enumerated included, of course.

Protocol extensions added inheritance to structs and enums and this should be made explicit.

Sent from my iPad

On Aug 24, 2016, at 12:55 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Aug 24, 2016, at 1:20 AM, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:
2016/08/23 20:52、Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> のメッセージ:

On Aug 23, 2016, at 10:34 PM, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:

2016/08/23 15:29、Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> のメッセージ:

On Aug 23, 2016, at 2:33 PM, Robert Widmann via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

2016/08/22 14:30、David Cordero via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> のメッセージ:

The problem:
At the moment, looking at the code of a class or a struct implementing a protocol, it is hard to know what methods are actually implementing the protocol and what other methods are just part of the code of the class or struct.

That seems like a feature, not a bug. Why should I as an author care whether a method contributes to a protocol conformance or not if the compiler can tell me that kind of information itself?

Being able to reason about your code, what it does, and what it’s for is undesirable?

That's not an answer to the question I asked. Why is this significant enough to warrant an entire keyword? The clutter of a whole keyword that does nothing but wait for a developer to make a source-compatible binary-breaking change to an interface does not seem worth it. Maybe you can convince me otherwise.

Same reason overriding a class method warrants a keyword. It expresses the purpose more clearly, and allows the compiler to catch mistakes for us.

That's just it: The class of mistakes one can make by not being explicit about overrides is significantly more dangerous than the class of mistakes caused by dead code leftover from trimming protocols.

I am in the middle of a large refactor of code that was originally Objective-C and then Swift written like Objective-C, to more idiomatic protocol-oriented Swift. I am finding that in Swift’s POP idiom, protocols with overrides are serving very nearly the same purpose that overrides were serving in the old design; hence, I don’t really think either is more or less dangerous than the other.

protocol MyProtocol {
    func myMethod() -> String
}

class MyClass: MyProtocol {

    conform func myMethod() -> String {
        return "Yuhuuu,I am conforming \\o// <smb://o//>"
    }

    func whatever() {
        print("I am a boring method and I don't conform anything")
    }
}

It would be something similar to the current keyword `override` but for protocols.

Apart from improving code readability, It would allow the detection, in compilation time, of errors due to code evolution. For example redundant methods that no longer conform anything once the requirement is removed from the protocol for whatever reason.

If you make a breaking change to a protocol like this, you should have gone through a deprecation cycle to indicate to your clients the appropriate changes you're going to make to the protocol. This aspect of the change seems to if not encourage, highlight, bad behavior.

What if it’s your own code and all the callers are internal? What if you’re still developing the protocol and haven’t released the API interface yet?

Then your concerns are local enough that you know where all implementations of the protocol lie and whether they require deletion or not. The point about deprecation cycles still stands in all the cases you mention. Just because the interface is private doesn't mean you can't take responsibility for keeping it as clean as you can.

Charles

tl;dr It seems like all of this can be subsumed by us warning about dead code.

Did you look at my examples earlier in the thread? Neither of those would be caught by warning about dead code.

The example involving the default implementation is most compelling, but it indicates that your proposed solution should focus on the protocol extension and not the implementing declaration. Perhaps reusing one of our existing keywords can help here

protocol P {
  func foo() {}
}

extension P {
  default func foo() {}
}

struct S: P {}

Of course, this change would be potentially source-breaking either way - I don't like the sound of an "optional keyword”.

I can come up with a similar example without the mistake being in the extension, though:

protocol P {
  func foo() {}
}

extension P {
  func foo() { print(“Default Behavior”) }
}

struct S: P {
  func foo() { print(“Specific Behavior”) }
}

So far, so good. But now I realize that the original protocol needs an argument:

protocol P {
  func foo(bar: String) {}
}

extension P {
  func foo(bar: String) { print(“Default Behavior; bar is \(bar)”) }
}

struct S: P {
  func foo() { print(“Specific Behavior”) } // Whoops, forgot to update this method, and now it won’t get called—and we of course won’t see the carnage until runtime.
}

Either way, we can all agree we need better diagnostics around these cases.

No doubt.

Charles

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

Chris, as I wrote above, this idea has been discussed previously on several
occasions, and the principal reason why it has been abandoned each time is
that it cannot accommodate retroactive modeling. I'll refer you again to
three previous threads discussing this and closely related matters:

https://lists.swift.org/pipermail/swift-evolution/
Week-of-Mon-20160104/005380.html
https://lists.swift.org/pipermail/swift-evolution/
Week-of-Mon-20160229/011792.html
https://lists.swift.org/pipermail/swift-evolution/
Week-of-Mon-20160425/015920.html

If, after familiarizing yourself with the previous discussions, you feel
like there is an aspect of the topic that has not yet been considered, then
of course feel free to start another discussion.

···

On Thu, Aug 25, 2016 at 5:36 PM, Christopher Kornher via swift-evolution < swift-evolution@swift.org> wrote:

On Aug 25, 2016, at 4:32 PM, Christopher Kornher <ckornher@me.com> wrote:

I hope that my brief email wasn’t the final word on this :(

Does anyone think that a proposal to require “override” for overrides of
protocol extension methods and variables (?) would be worth exploring?

This would address a number of the issues raised in this thread, but not
all.

My intention is not to derail this thread, and I believe that the original
topic of this thread, explicit protocol conformance, is worth exploring. I
respond here because of these topics are strongly related. I will start a
new thread, if there is interest.

It is possible that tooling could address the remaining issues with
overrides. JetBrains products, for example, provide navigable icons to
overridden methods. There is no reason that Xcode and other tools could not
automatically insert indicators like:

class MyClass: MyProtocol {

< conforms >
func myMethod() -> String {
         return “..."
    }

class MyClass2: MyProtocol1, MyProtocol2 {

< conforms MyProtocol2 >
func myMethod() -> String {
        return “..."
    }

Of course, there is no reason that tooling can’t replace “override”
completely:

class MyClass: MyOtherClass, MyProtocol1, MyProtocol2 {

< conforms MyProtocol2 >
< overrides TheParentClassOfMyOtherClass>
func myMethod() -> String {
        return “..."
    }

Replace "<…>” with the navigable graphic of your choice and assume that
user preferences would exist to show/hide these indicators.

My cut and paste error left out this part:

The roles of language and tooling in making code understandable is largely
a matter of opinion. I personally like the current use of “override” since
overriding is a common cause of serious programming errors and a mechanism
for protecting against them should be built into the language and now,
extended to overrides of protocol extensions.

It is interesting that adding “override” to structs and enums would help
to open the door to true inheritance (not polymorphism) for structs and
possibly even enums, if anyone knows of a use for that. This is a feature
that I could have used on a few projects, but there are far more important
features in the queue, and that discussion should probably wait until after
Swift 4, if it happens at all.

- Chris K

On Aug 24, 2016, at 11:13 AM, Christopher Kornher via swift-evolution < > swift-evolution@swift.org> wrote:

Requiring "override" when anything overrides a method defined in a
protocol extension should be added - structure and enumerated included, of
course.

Protocol extensions added inheritance to structs and enums and this should
be made explicit.

Sent from my iPad

On Aug 24, 2016, at 12:55 AM, Charles Srstka via swift-evolution < > swift-evolution@swift.org> wrote:

On Aug 24, 2016, at 1:20 AM, Robert Widmann <devteam.codafi@gmail.com> > wrote:

2016/08/23 20:52、Charles Srstka <cocoadev@charlessoft.com> のメッセージ:

On Aug 23, 2016, at 10:34 PM, Robert Widmann <devteam.codafi@gmail.com> > wrote:

2016/08/23 15:29、Charles Srstka <cocoadev@charlessoft.com> のメッセージ:

On Aug 23, 2016, at 2:33 PM, Robert Widmann via swift-evolution < > swift-evolution@swift.org> wrote:

2016/08/22 14:30、David Cordero via swift-evolution <
swift-evolution@swift.org> のメッセージ:

*The problem:*
At the moment, looking at the code of a class or a struct implementing a
protocol, it is hard to know what methods are actually implementing the
protocol and what other methods are just part of the code of the class or
struct.

That seems like a feature, not a bug. Why should I as an author care
whether a method contributes to a protocol conformance or not if the
compiler can tell me that kind of information itself?

Being able to reason about your code, what it does, and what it’s for is
undesirable?

That's not an answer to the question I asked. Why is this significant
enough to warrant an entire keyword? The clutter of a whole keyword that
does nothing but wait for a developer to make a source-compatible
binary-breaking change to an interface does not seem worth it. Maybe you
can convince me otherwise.

Same reason overriding a class method warrants a keyword. It expresses the
purpose more clearly, and allows the compiler to catch mistakes for us.

That's just it: The class of mistakes one can make by not being explicit
about overrides is significantly more dangerous than the class of mistakes
caused by dead code leftover from trimming protocols.

I am in the middle of a large refactor of code that was originally
Objective-C and then Swift written like Objective-C, to more idiomatic
protocol-oriented Swift. I am finding that in Swift’s POP idiom, protocols
with overrides are serving very nearly the same purpose that overrides were
serving in the old design; hence, I don’t really think either is more or
less dangerous than the other.


protocol MyProtocol {
    func myMethod() -> String
}

class MyClass: MyProtocol {

    *conform* func myMethod() -> String {
        return "Yuhuuu,I am conforming \\o//"
    }

    func whatever() {
        print("I am a boring method and I don't conform anything")
    }
}

It would be something similar to the current keyword `override` but for
protocols.

Apart from improving code readability, It would allow the detection, in
compilation time, of errors due to code evolution. For example redundant
methods that no longer conform anything once the requirement is removed
from the protocol for whatever reason.

If you make a breaking change to a protocol like this, you should have
gone through a deprecation cycle to indicate to your clients the
appropriate changes you're going to make to the protocol. This aspect of
the change seems to if not encourage, highlight, bad behavior.

What if it’s your own code and all the callers are internal? What if
you’re still developing the protocol and haven’t released the API interface
yet?

Then your concerns are local enough that you know where *all* implementations
of the protocol lie and whether they require deletion or not. The point
about deprecation cycles still stands in all the cases you mention. Just
because the interface is private doesn't mean you can't take responsibility
for keeping it as clean as you can.

Charles

tl;dr It seems like all of this can be subsumed by us warning about dead
code.

Did you look at my examples earlier in the thread? Neither of those would
be caught by warning about dead code.

The example involving the default implementation is most compelling, but
it indicates that your proposed solution should focus on the protocol
extension and not the implementing declaration. Perhaps reusing one of our
existing keywords can help here

protocol P {
  func foo() {}
}

extension P {
  default func foo() {}
}

struct S: P {}

Of course, this change would be potentially source-breaking either way - I
don't like the sound of an "optional keyword”.

I can come up with a similar example without the mistake being in the
extension, though:

protocol P {
func foo() {}
}

extension P {
func foo() { print(“Default Behavior”) }
}

struct S: P {
func foo() { print(“Specific Behavior”) }
}

So far, so good. But now I realize that the original protocol needs an
argument:

protocol P {
func foo(bar: String) {}
}

extension P {
func foo(bar: String) { print(“Default Behavior; bar is \(bar)”) }
}

struct S: P {
func foo() { print(“Specific Behavior”) } // Whoops, forgot to update this
method, and now it won’t get called—and we of course won’t see the
carnage until runtime.
}

Either way, we can all agree we need better diagnostics around these cases.

No doubt.

Charles

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Is there a reason that adding a “retro” keyword on extensions meant to retroactively apply a protocol is unacceptable?

Charles

···

On Aug 25, 2016, at 6:44 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

Chris, as I wrote above, this idea has been discussed previously on several occasions, and the principal reason why it has been abandoned each time is that it cannot accommodate retroactive modeling. I'll refer you again to three previous threads discussing this and closely related matters:

Yes, and it's covered in those previous threads. In brief, not all
retroactive modeling involves extending a type:

* A vendor supplies you with a closed-source library with a struct S that
conforms to standard library protocol P.

* Protocol P requires a method named foo(), so struct S has its own
implementation of foo().

* You extend protocol P by adding a new default implementation of foo().

This cannot be done if a keyword is required for overriding a default
implementation. There is also nowhere for you to append any sort of "retro"
keyword anywhere, because no part of your own code extends S in any way.

Please, please take the time to study the previous threads; we should not
be re-playing existing discussions four or five times on this list.

···

On Thu, Aug 25, 2016 at 10:06 PM, Charles Srstka <cocoadev@charlessoft.com> wrote:

Is there a reason that adding a “retro” keyword on extensions meant to
retroactively apply a protocol is unacceptable?

Charles

On Aug 25, 2016, at 6:44 PM, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> wrote:

Chris, as I wrote above, this idea has been discussed previously on
several occasions, and the principal reason why it has been abandoned each
time is that it cannot accommodate retroactive modeling. I'll refer you
again to three previous threads discussing this and closely related matters:

How is this a problem, though? The implementation of foo() in S will not break, because it’s already been compiled in. The change will only affect code that is subsequently compiled with your extension of P in place. And it’ll be doing its job; making sure that your code to implement the protocol is there deliberately, and preventing you from accidentally mistyping the method name and thus silently failing to override the default implementation.

Charles

···

On Aug 25, 2016, at 10:24 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

Yes, and it's covered in those previous threads. In brief, not all retroactive modeling involves extending a type:

* A vendor supplies you with a closed-source library with a struct S that conforms to standard library protocol P.

* Protocol P requires a method named foo(), so struct S has its own implementation of foo().

* You extend protocol P by adding a new default implementation of foo().

This cannot be done if a keyword is required for overriding a default implementation. There is also nowhere for you to append any sort of "retro" keyword anywhere, because no part of your own code extends S in any way.

Please, please take the time to study the previous threads; we should not be re-playing existing discussions four or five times on this list.

So you're saying that the compiler should let you compile your extension of
P, even though it knows that the default implementation of `foo()` is not
explicitly overridden by S. Fine.
Now suppose the library is not closed-source; you're including it in your
project and compiling it along with your own code. Are you supposed to fork
the library?

···

On Thu, Aug 25, 2016 at 11:05 PM, Charles Srstka <cocoadev@charlessoft.com> wrote:

On Aug 25, 2016, at 10:24 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

Yes, and it's covered in those previous threads. In brief, not all
retroactive modeling involves extending a type:

* A vendor supplies you with a closed-source library with a struct S that
conforms to standard library protocol P.

* Protocol P requires a method named foo(), so struct S has its own
implementation of foo().

* You extend protocol P by adding a new default implementation of foo().

This cannot be done if a keyword is required for overriding a default
implementation. There is also nowhere for you to append any sort of "retro"
keyword anywhere, because no part of your own code extends S in any way.

Please, please take the time to study the previous threads; we should not
be re-playing existing discussions four or five times on this list.

How is this a problem, though? The implementation of foo() in S will not
break, because it’s already been compiled in. The change will only affect
code that is subsequently compiled with your extension of P in place. And
it’ll be doing its job; making sure that your code to implement the
protocol is there deliberately, and preventing you from accidentally
mistyping the method name and thus silently failing to override the default
implementation.

Even if the library is open-source, you'll presumably be building in as its own target, which will be including only library code and not your extension, and linking it into the application in a later stage of the build process.

Charles

···

On Aug 25, 2016, at 11:48 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Thu, Aug 25, 2016 at 11:05 PM, Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> wrote:

On Aug 25, 2016, at 10:24 PM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

Yes, and it's covered in those previous threads. In brief, not all retroactive modeling involves extending a type:

* A vendor supplies you with a closed-source library with a struct S that conforms to standard library protocol P.

* Protocol P requires a method named foo(), so struct S has its own implementation of foo().

* You extend protocol P by adding a new default implementation of foo().

This cannot be done if a keyword is required for overriding a default implementation. There is also nowhere for you to append any sort of "retro" keyword anywhere, because no part of your own code extends S in any way.

Please, please take the time to study the previous threads; we should not be re-playing existing discussions four or five times on this list.

How is this a problem, though? The implementation of foo() in S will not break, because it’s already been compiled in. The change will only affect code that is subsequently compiled with your extension of P in place. And it’ll be doing its job; making sure that your code to implement the protocol is there deliberately, and preventing you from accidentally mistyping the method name and thus silently failing to override the default implementation.

So you're saying that the compiler should let you compile your extension of P, even though it knows that the default implementation of `foo()` is not explicitly overridden by S. Fine.
Now suppose the library is not closed-source; you're including it in your project and compiling it along with your own code. Are you supposed to fork the library?

Yes, and it's covered in those previous threads. In brief, not all
retroactive modeling involves extending a type:

* A vendor supplies you with a closed-source library with a struct S that
conforms to standard library protocol P.

* Protocol P requires a method named foo(), so struct S has its own
implementation of foo().

* You extend protocol P by adding a new default implementation of foo().

This cannot be done if a keyword is required for overriding a default
implementation. There is also nowhere for you to append any sort of "retro"
keyword anywhere, because no part of your own code extends S in any way.

Please, please take the time to study the previous threads; we should not
be re-playing existing discussions four or five times on this list.

How is this a problem, though? The implementation of foo() in S will not
break, because it’s already been compiled in. The change will only affect
code that is subsequently compiled with your extension of P in place. And
it’ll be doing its job; making sure that your code to implement the
protocol is there deliberately, and preventing you from accidentally
mistyping the method name and thus silently failing to override the default
implementation.

So you're saying that the compiler should let you compile your extension
of P, even though it knows that the default implementation of `foo()` is
not explicitly overridden by S. Fine.
Now suppose the library is not closed-source; you're including it in your
project and compiling it along with your own code. Are you supposed to fork
the library?

Even if the library is open-source, you'll presumably be building in as
its own target, which will be including only library code and not your
extension, and linking it into the application in a later stage of the
build process.

I made the same argument eight months ago:

* Another option might be to allow imported definitions to be used by a
conformance without the `override` marking to support retroactive modeling
while requiring definitions in the same module as the conformance to
explicitly specify the `override`.*

But Brent Royal-Gordon had a good point:

But the same problem exists if you want to do this to `internal` types

···

On Fri, Aug 26, 2016 at 1:53 AM, Charles Srstka <cocoadev@charlessoft.com> wrote:

On Aug 25, 2016, at 11:48 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
On Thu, Aug 25, 2016 at 11:05 PM, Charles Srstka <cocoadev@charlessoft.com > > wrote:

On Aug 25, 2016, at 10:24 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

using a `private` protocol. There you *could* make the protocol `internal`
and call `override` in all the right places, but if the protocol is an
implementation detail of one particular file, why should you?

If the protocol is private, than to code outside that file, the protocol effectively doesn’t exist, since code in protocol extensions is statically dispatched (this is also true to code in your hypothetical library). So no need for “override” there.

If the protocol is internal, than code elsewhere in your app can see it, and thus they should have to override, for the same reason that if you added a superclass method that some subclass was already using, you’d need to add “override”.

Charles

···

On Aug 26, 2016, at 2:22 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Aug 26, 2016 at 1:53 AM, Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> wrote:

On Aug 25, 2016, at 11:48 PM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

On Thu, Aug 25, 2016 at 11:05 PM, Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> wrote:

On Aug 25, 2016, at 10:24 PM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

Yes, and it's covered in those previous threads. In brief, not all retroactive modeling involves extending a type:

* A vendor supplies you with a closed-source library with a struct S that conforms to standard library protocol P.

* Protocol P requires a method named foo(), so struct S has its own implementation of foo().

* You extend protocol P by adding a new default implementation of foo().

This cannot be done if a keyword is required for overriding a default implementation. There is also nowhere for you to append any sort of "retro" keyword anywhere, because no part of your own code extends S in any way.

Please, please take the time to study the previous threads; we should not be re-playing existing discussions four or five times on this list.

How is this a problem, though? The implementation of foo() in S will not break, because it’s already been compiled in. The change will only affect code that is subsequently compiled with your extension of P in place. And it’ll be doing its job; making sure that your code to implement the protocol is there deliberately, and preventing you from accidentally mistyping the method name and thus silently failing to override the default implementation.

So you're saying that the compiler should let you compile your extension of P, even though it knows that the default implementation of `foo()` is not explicitly overridden by S. Fine.
Now suppose the library is not closed-source; you're including it in your project and compiling it along with your own code. Are you supposed to fork the library?

Even if the library is open-source, you'll presumably be building in as its own target, which will be including only library code and not your extension, and linking it into the application in a later stage of the build process.

I made the same argument eight months ago:

> Another option might be to allow imported definitions to be used by a conformance without the `override` marking to support retroactive modeling while requiring definitions in the same module as the conformance to explicitly specify the `override`.

But Brent Royal-Gordon had a good point:

But the same problem exists if you want to do this to `internal` types using a `private` protocol. There you *could* make the protocol `internal` and call `override` in all the right places, but if the protocol is an implementation detail of one particular file, why should you?

Yes, and it's covered in those previous threads. In brief, not all
retroactive modeling involves extending a type:

* A vendor supplies you with a closed-source library with a struct S
that conforms to standard library protocol P.

* Protocol P requires a method named foo(), so struct S has its own
implementation of foo().

* You extend protocol P by adding a new default implementation of foo().

This cannot be done if a keyword is required for overriding a default
implementation. There is also nowhere for you to append any sort of "retro"
keyword anywhere, because no part of your own code extends S in any way.

Please, please take the time to study the previous threads; we should
not be re-playing existing discussions four or five times on this list.

How is this a problem, though? The implementation of foo() in S will not
break, because it’s already been compiled in. The change will only affect
code that is subsequently compiled with your extension of P in place. And
it’ll be doing its job; making sure that your code to implement the
protocol is there deliberately, and preventing you from accidentally
mistyping the method name and thus silently failing to override the default
implementation.

So you're saying that the compiler should let you compile your extension
of P, even though it knows that the default implementation of `foo()` is
not explicitly overridden by S. Fine.
Now suppose the library is not closed-source; you're including it in your
project and compiling it along with your own code. Are you supposed to fork
the library?

Even if the library is open-source, you'll presumably be building in as
its own target, which will be including only library code and not your
extension, and linking it into the application in a later stage of the
build process.

I made the same argument eight months ago:

>

* Another option might be to allow imported definitions to be used by a
conformance without the `override` marking to support retroactive modeling
while requiring definitions in the same module as the conformance to
explicitly specify the `override`.*

But Brent Royal-Gordon had a good point:

But the same problem exists if you want to do this to `internal` types

using a `private` protocol. There you *could* make the protocol `internal`
and call `override` in all the right places, but if the protocol is an
implementation detail of one particular file, why should you?

If the protocol is private, than to code outside that file, the protocol
effectively doesn’t exist, since code in protocol extensions is statically
dispatched (this is also true to code in your hypothetical library). So no
need for “override” there.

That is incorrect. If it's a protocol requirement, it's dynamically
dispatched. If I conform an internal type to a private protocol and use
that type in the same file where the protocol is defined, that type
conforms to the protocol. You would have no way of appending the `override`
keyword to the relevant overrides without making the protocol internally
visible.

If the protocol is internal, than code elsewhere in your app can see it,

···

On Fri, Aug 26, 2016 at 2:30 AM, Charles Srstka <cocoadev@charlessoft.com> wrote:

On Aug 26, 2016, at 2:22 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
On Fri, Aug 26, 2016 at 1:53 AM, Charles Srstka <cocoadev@charlessoft.com> > wrote:

On Aug 25, 2016, at 11:48 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
On Thu, Aug 25, 2016 at 11:05 PM, Charles Srstka <cocoadev@charlessoft.c >> > wrote:

On Aug 25, 2016, at 10:24 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

and thus they should have to override, for the same reason that if you
added a superclass method that some subclass was already using, you’d need
to add “override”.

Charles

We were speaking of extending a protocol. This means that either 1) the method we add lives only in the extension, is statically dispatched, and thus does not exist to code that cannot see the extension, or 2) the code that cannot see the extension has been written as if the extension did not exist, and thus must already have another implementation of the method. In neither case does the extension affect the behavior of code that cannot see it.

If the protocol is private, then your internal type cannot see it. The internal type, which lives in complete blissful ignorance of the private protocol, can coincidentally implement one of the methods, but it is not conforming to the protocol in doing so, and thus does not have any need of adding a keyword to indicate that it is so conforming. If the match in nomenclature is more than coincidental, the intention falls on the private protocol, not the internal type.

The point of the keyword is to clarify *intentions.* If I am declaring my type as conforming to a protocol, and I am implementing methods that are required by the protocol, I should tell the compiler that the purpose of these methods is to satisfy the protocol. If I am implementing a protocol method that already has a default, I should indicate that I’m doing that on purpose, as well. If I *am not conforming* to the protocol and somebody *else* is adding conformance in an extension, then it’s not my problem and the person doing the conforming should be the one to declare their intent.

Charles

···

On Aug 26, 2016, at 3:39 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Aug 26, 2016 at 2:30 AM, Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> wrote:

On Aug 26, 2016, at 2:22 AM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

On Fri, Aug 26, 2016 at 1:53 AM, Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> wrote:

On Aug 25, 2016, at 11:48 PM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

On Thu, Aug 25, 2016 at 11:05 PM, Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> wrote:

On Aug 25, 2016, at 10:24 PM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

Yes, and it's covered in those previous threads. In brief, not all retroactive modeling involves extending a type:

* A vendor supplies you with a closed-source library with a struct S that conforms to standard library protocol P.

* Protocol P requires a method named foo(), so struct S has its own implementation of foo().

* You extend protocol P by adding a new default implementation of foo().

This cannot be done if a keyword is required for overriding a default implementation. There is also nowhere for you to append any sort of "retro" keyword anywhere, because no part of your own code extends S in any way.

Please, please take the time to study the previous threads; we should not be re-playing existing discussions four or five times on this list.

How is this a problem, though? The implementation of foo() in S will not break, because it’s already been compiled in. The change will only affect code that is subsequently compiled with your extension of P in place. And it’ll be doing its job; making sure that your code to implement the protocol is there deliberately, and preventing you from accidentally mistyping the method name and thus silently failing to override the default implementation.

So you're saying that the compiler should let you compile your extension of P, even though it knows that the default implementation of `foo()` is not explicitly overridden by S. Fine.
Now suppose the library is not closed-source; you're including it in your project and compiling it along with your own code. Are you supposed to fork the library?

Even if the library is open-source, you'll presumably be building in as its own target, which will be including only library code and not your extension, and linking it into the application in a later stage of the build process.

I made the same argument eight months ago:

> Another option might be to allow imported definitions to be used by a conformance without the `override` marking to support retroactive modeling while requiring definitions in the same module as the conformance to explicitly specify the `override`.

But Brent Royal-Gordon had a good point:

But the same problem exists if you want to do this to `internal` types using a `private` protocol. There you *could* make the protocol `internal` and call `override` in all the right places, but if the protocol is an implementation detail of one particular file, why should you?

If the protocol is private, than to code outside that file, the protocol effectively doesn’t exist, since code in protocol extensions is statically dispatched (this is also true to code in your hypothetical library). So no need for “override” there.

That is incorrect. If it's a protocol requirement, it's dynamically dispatched. If I conform an internal type to a private protocol and use that type in the same file where the protocol is defined, that type conforms to the protocol. You would have no way of appending the `override` keyword to the relevant overrides without making the protocol internally visible.

Yes, and it's covered in those previous threads. In brief, not all
retroactive modeling involves extending a type:

* A vendor supplies you with a closed-source library with a struct S
that conforms to standard library protocol P.

* Protocol P requires a method named foo(), so struct S has its own
implementation of foo().

* You extend protocol P by adding a new default implementation of foo().

This cannot be done if a keyword is required for overriding a default
implementation. There is also nowhere for you to append any sort of "retro"
keyword anywhere, because no part of your own code extends S in any way.

Please, please take the time to study the previous threads; we should
not be re-playing existing discussions four or five times on this list.

How is this a problem, though? The implementation of foo() in S will
not break, because it’s already been compiled in. The change will only
affect code that is subsequently compiled with your extension of P in
place. And it’ll be doing its job; making sure that your code to implement
the protocol is there deliberately, and preventing you from accidentally
mistyping the method name and thus silently failing to override the default
implementation.

So you're saying that the compiler should let you compile your extension
of P, even though it knows that the default implementation of `foo()` is
not explicitly overridden by S. Fine.
Now suppose the library is not closed-source; you're including it in
your project and compiling it along with your own code. Are you supposed to
fork the library?

Even if the library is open-source, you'll presumably be building in as
its own target, which will be including only library code and not your
extension, and linking it into the application in a later stage of the
build process.

I made the same argument eight months ago:

>

* Another option might be to allow imported definitions to be used by a
conformance without the `override` marking to support retroactive modeling
while requiring definitions in the same module as the conformance to
explicitly specify the `override`.*

But Brent Royal-Gordon had a good point:

But the same problem exists if you want to do this to `internal` types

using a `private` protocol. There you *could* make the protocol `internal`
and call `override` in all the right places, but if the protocol is an
implementation detail of one particular file, why should you?

If the protocol is private, than to code outside that file, the protocol
effectively doesn’t exist, since code in protocol extensions is statically
dispatched (this is also true to code in your hypothetical library). So no
need for “override” there.

That is incorrect. If it's a protocol requirement, it's dynamically
dispatched. If I conform an internal type to a private protocol and use
that type in the same file where the protocol is defined, that type
conforms to the protocol. You would have no way of appending the `override`
keyword to the relevant overrides without making the protocol internally
visible.

We were speaking of extending a protocol.

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

This means that either 1) the method we add lives only in the extension, is

···

On Fri, Aug 26, 2016 at 3:55 AM, Charles Srstka <cocoadev@charlessoft.com> wrote:

On Aug 26, 2016, at 3:39 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
On Fri, Aug 26, 2016 at 2:30 AM, Charles Srstka <cocoadev@charlessoft.com> > wrote:

On Aug 26, 2016, at 2:22 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
On Fri, Aug 26, 2016 at 1:53 AM, Charles Srstka <cocoadev@charlessoft.com >> > wrote:

On Aug 25, 2016, at 11:48 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
On Thu, Aug 25, 2016 at 11:05 PM, Charles Srstka <cocoadev@charlessoft.c >>> > wrote:

On Aug 25, 2016, at 10:24 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

statically dispatched, and thus does not exist to code that cannot see the
extension, or 2) the code that cannot see the extension has been written as
if the extension did not exist, and thus must already have another
implementation of the method. In neither case does the extension affect the
behavior of code that cannot see it.

If the protocol is private, then your internal type cannot see it. The
internal type, which lives in complete blissful ignorance of the private
protocol, can coincidentally implement one of the methods, but it is not
conforming to the protocol in doing so, and thus does not have any need of
adding a keyword to indicate that it is so conforming. If the match in
nomenclature is more than coincidental, the intention falls on the private
protocol, not the internal type.

The point of the keyword is to clarify *intentions.* If I am declaring my
type as conforming to a protocol, and I am implementing methods that are
required by the protocol, I should tell the compiler that the purpose of
these methods is to satisfy the protocol. If I am implementing a protocol
method that already has a default, I should indicate that I’m doing that on
purpose, as well. If I *am not conforming* to the protocol and somebody
*else* is adding conformance in an extension, then it’s not my problem and
the person doing the conforming should be the one to declare their intent.

Charles

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:

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.

Charles

···

On Aug 26, 2016, at 4:02 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
On Aug 22, 2016, at 4:30 PM, David Cordero via swift-evolution <swift-evolution@swift.org> wrote:

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.

···

On Fri, Aug 26, 2016 at 4:24 AM, Charles Srstka <cocoadev@charlessoft.com> wrote:

On Aug 26, 2016, at 4:02 AM, Xiaodi Wu <xiaodi.wu@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@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.

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

···

On Aug 26, 2016, at 4:34 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Aug 26, 2016 at 4:24 AM, Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> wrote:

On Aug 26, 2016, at 4:02 AM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@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@swift.org <mailto:swift-evolution@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.