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