[swift-evolution] Keyword for protocol conformance

Xiaodi Wu xiaodi.wu at gmail.com
Fri Aug 26 14:34:52 CDT 2016


On Fri, Aug 26, 2016 at 2:29 PM, Charles Srstka <cocoadev at charlessoft.com>
wrote:

> On Aug 26, 2016, at 1:45 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
>
> On Fri, Aug 26, 2016 at 1:27 PM, Charles Srstka <cocoadev at charlessoft.com>
>  wrote:
>
>> On Aug 26, 2016, at 11:02 AM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>
>>
>> Really? I wasn't aware that you could work around the `override` keyword
>> (the one that's required for classes). How do you do that?
>>
>>
>> By implementing the subclass’s method before the superclass’s. You can
>> try this yourself:
>>
>> - - - Library code: - - -
>>
>> open class Superclass {
>>     public init() {}
>>     public func foo() {
>>         print("foo called in library")
>>     }
>> }
>>
>> - - - App code: - - -
>>
>> import FooLibrary
>>
>> class Subclass: Superclass {
>>     func bar() { print("bar called in the app") }
>> }
>>
>> let obj = Subclass()
>>
>> obj.foo()
>>
>> - - - output: - - -
>>
>> *foo called in library*
>> *Program ended with exit code: 0*
>>
>> - - - - - -
>>
>> Now: Change the library code to:
>>
>> open class Superclass {
>>     public init() {}
>>     public func foo() {
>>         print("foo called in library")
>>         bar()
>>     }
>>
>>     // Hey look, I didn't even use that stupid new 'open' keyword.
>>     public func bar() { print("bar called in library") }
>> }
>>
>> - - - Run the app again without compiling it, and: - - -
>>
>> *foo called in library*
>> *bar called in the app*
>> *Program ended with exit code: 0*
>>
>> - - -
>>
>> Voilà: I overrode a method (a supposedly non-overridable one, at that)
>> with no “override” keyword.
>>
>
> This is clearly a bug in the implementation, not part of the design.
> Expect it to be fixed as the code for `open` matures. It's certainly not a
> precedent to be emulated for designing another feature.
>
>
> It’s a side effect of using straight string equality for conformance,
> which is the status quo that several proposals here have been hoping to
> change with protocols.
>
> Just as File A in your earlier example can implement a protocol method
>> without realizing it, Subclass here has unintentionally overridden a
>> superclass method. This is because ‘override’ does not, to the best of my
>> knowledge, mean anything to the actual machine code that is produced;
>> rather, it signals the developer’s *intent,* thus allowing the compiler to
>> assist in making sure the developer does the right thing.
>>
>> I’d actually argue that the example above is a much, much bigger problem
>> than the objection you raised, as it can actually produce unintended
>> behavior at runtime, whereas the example with protocols can’t.
>>
>> As for the protocol example, I’d like to refine Option 3 from last night
>> slightly:
>>
>> Option 4: A keyword is required on a method declaration if and only if
>> the containing type is declared as conforming to its protocol, either in
>> its definition or in an extension that is visible within the current scope.
>>
>
> Extensions are not first-class entities and have no visibility of their
> own.
>
>
> I didn’t express that very well. Let me clarify what I mean:
>
> internal struct S {}
>
> private protocol P {
>     func foo()
> }
>
> extension S: P {
>     func foo() {}
> }
>
> - - - choose “Generated Interface” and you get: - - -
>
> internal struct S {
> }
>
>
> extension S {
>
>     internal func foo()
> }
>
> - - -
>
> While the extension is visible, the fact that it adds conformance to P is
> not. Therefore, as far as code outside this file is concerned, there is no
> conformance to P.
>

That's correct, but why should the compiler accept the code in this file,
when both S and P are visible, and S is not overriding default
implementations in P as it should?

>
> In any case, you have not solved the problem, which has nothing to do with
> whether something is "reasonable to know": when a default implementation A
> is overridden by implementation B, implementation A may be visible only in
> a *more restricted* access scope than implementation B. (This is not the
> case with overriding superclass members in subclasses.) It can be perfectly
> "reasonable to know" about both A and B, but there is still no way you can
> indicate this knowledge by appending a keyword to the declaration for
> implementation B if the access scope for implementation A is unutterable
> where B is declared.
>
>
> Could you provide an example of code where this would present a problem?
>

I'm still talking about the same example. How do you rationalize your
statement that no keyword is needed because it's not "reasonable to know"
about both S and P when compiling the file in which P is declared?


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


More information about the swift-evolution mailing list