[Pitch] Requiring proactive overrides for default protocol implementations.


(Erica Sadun) #1

From the Swift Programming Language: Methods on a subclass that override the superclass’s implementation are marked with override—overriding a method by accident, without override, is detected by the compiler as an error. The compiler also detects methods with override that don’t actually override any method in the superclass.

I would like to extend this cautious approach to protocols, forcing the developer to deliberately override an implementation that’s inherited from a protocol extension. This would prevent accidental overrides and force the user to proactively choose to implement a version of a protocol member that already exists in the protocol extension.

I envision this as using the same `override` keyword that’s used in class based inheritance but extend it to protocol inheritance:

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation … }
}

type B: A {

    override required func foo () { … overrides implementation … }
}

I’d also like to bring up two related topics, although they probably should at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two unrelated protocols both require the same member and offer different default implementations. Can they specify which implementation to accept or somehow run both?

type B: A, C {
    override required func foo() { A.foo(); C.foo() }
}

Related topic 2: How can a consumer “inherit” the behavior of the default implementation (like calling super.foo() in classes) and then extend that behavior further. This is a bit similar to how the initialization chaining works. I’d like to be able to call A.foo() and then add custom follow-on behavior rather than entirely replacing the behavior.

type B: A {
    override required func foo() { A.foo(); … my custom behavior … }
}

cc’ing in Jordan who suggested a new thread on this and Doug, who has already expressed some objections so I want him to have the opportunity to bring that discussion here.

— E


(Douglas Gregor) #2

From the Swift Programming Language: Methods on a subclass that override the superclass’s implementation are marked with override—overriding a method by accident, without override, is detected by the compiler as an error. The compiler also detects methods with override that don’t actually override any method in the superclass.

I would like to extend this cautious approach to protocols, forcing the developer to deliberately override an implementation that’s inherited from a protocol extension. This would prevent accidental overrides and force the user to proactively choose to implement a version of a protocol member that already exists in the protocol extension.

I envision this as using the same `override` keyword that’s used in class based inheritance but extend it to protocol inheritance:

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation … }
}

type B: A {

    override required func foo () { … overrides implementation … }
}

A couple questions about your pitch:

1) What is “required” doing there?

2) Is “override” only required when there is a default implementation of the protocol requirement, or is it required whenever you are implementing a protocol requirement?

  * If the former, it might be the case that it’s too easy to forget to add the “override” keyword (because it’s needed for some implementations of protocol requirements but not others), which undercuts the value of having it.

  * If the latter, “override” is probably the wrong keyword because it’s not overriding anything in the common case of implementing a non-defaulted requirement.

I’d also like to bring up two related topics, although they probably should at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two unrelated protocols both require the same member and offer different default implementations. Can they specify which implementation to accept or somehow run both?

type B: A, C {
    override required func foo() { A.foo(); C.foo() }
}

I think the right answer here is for the compiler to produce an ambiguity if you don’t implement the requirement yourself, and then solving your “related topic 2” lets you choose which implementation you want.

Related topic 2: How can a consumer “inherit” the behavior of the default implementation (like calling super.foo() in classes) and then extend that behavior further. This is a bit similar to how the initialization chaining works. I’d like to be able to call A.foo() and then add custom follow-on behavior rather than entirely replacing the behavior.

type B: A {
    override required func foo() { A.foo(); … my custom behavior … }
}

Seems totally reasonable to me. One ugly syntax: A.foo(self)(), leveraging the currying of self?

cc’ing in Jordan who suggested a new thread on this and Doug, who has already expressed some objections so I want him to have the opportunity to bring that discussion here.

My objections are described here:

  http://thread.gmane.org/gmane.comp.lang.swift.devel/1799/focus=1831

Essentially, my argument is that the point of “override” (as pitched above) is to declare the user’s intent to implement a requirement. I feel that the explicit protocol conformance ("type B : A”) declares that intent, and that various common conventions (e.g., one conformance per extension, where the extension is primarily there to conform to the protocol) reinforce intent well enough for the compiler to do a good job here. I’d prefer that over another boilerplate-y keyword.

  - Doug

···

On Apr 27, 2016, at 10:10 AM, Erica Sadun <erica@ericasadun.com> wrote:


(Tod Cunningham) #3

Having to specify override to override the implementation of protocol leads one further down the path that the protocol’s implementation is actually being overridden. However, currently that is not the case. If the protocol’s definition was actually being overridden, I think you would have a good case. But swift, as it exists today, will still call the protocol’s default implementation if accessed through the protocol type. So it isn’t really overriding the implementation of the protocol:

For example:

protocol Test {

}

extension Test {

    var hello: String {

        return "hello"

    }

}

class A: Test {

}

class B: Test {

    var hello: String {

        return "see ya"

    }

}

print( A().hello ) // hello

print( B().hello ) // see ya

let test1: Test = A()

print( test1.hello ) // hello

let test2: Test = B()

print( test2.hello ) // hello <== not "see ya"

Thanks,

Tod Cunningham

···

From: <swift-evolution-bounces@swift.org<mailto:swift-evolution-bounces@swift.org>> on behalf of Erica Sadun via swift-evolution <swift-evolution@swift.org<mailto:swift-evolution@swift.org>>
Reply-To: Erica Sadun <erica@ericasadun.com<mailto:erica@ericasadun.com>>
Date: Wednesday, April 27, 2016 at 1:10 PM
To: swift-evolution <swift-evolution@swift.org<mailto:swift-evolution@swift.org>>, Jordan Rose <jordan_rose@apple.com<mailto:jordan_rose@apple.com>>, Douglas Gregor <dgregor@apple.com<mailto:dgregor@apple.com>>
Subject: [swift-evolution] [Pitch] Requiring proactive overrides for default protocol implementations.

From the Swift Programming Language: Methods on a subclass that override the superclass’s implementation are marked with override—overriding a method by accident, without override, is detected by the compiler as an error. The compiler also detects methods with override that don’t actually override any method in the superclass.

I would like to extend this cautious approach to protocols, forcing the developer to deliberately override an implementation that’s inherited from a protocol extension. This would prevent accidental overrides and force the user to proactively choose to implement a version of a protocol member that already exists in the protocol extension.

I envision this as using the same `override` keyword that’s used in class based inheritance but extend it to protocol inheritance:

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation … }
}

type B: A {

    override required func foo () { … overrides implementation … }
}

I’d also like to bring up two related topics, although they probably should at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two unrelated protocols both require the same member and offer different default implementations. Can they specify which implementation to accept or somehow run both?

type B: A, C {
    override required func foo() { A.foo(); C.foo() }
}

Related topic 2: How can a consumer “inherit” the behavior of the default implementation (like calling super.foo() in classes) and then extend that behavior further. This is a bit similar to how the initialization chaining works. I’d like to be able to call A.foo() and then add custom follow-on behavior rather than entirely replacing the behavior.

type B: A {
    override required func foo() { A.foo(); … my custom behavior … }
}

cc’ing in Jordan who suggested a new thread on this and Doug, who has already expressed some objections so I want him to have the opportunity to bring that discussion here.

— E


(Vladimir) #4

IMO very important questions and suggestions.

Firstly, wanted to ask about "required" keyword in your examples - do we expect to have it in meaning "implementing the protocol method" ? I'd like to have it very much.

* About the "override" keyword : +1 from me. We should be clear and explicit if we override method from default protocol implementation.
Right now (as I understand) we have some mess when class and protocol has the same methods. For example :

protocol A {}

extension A {
     func y() {print("Y in A")}
}

class C:A {
     func y() {
         print("Y in C")
     }
}

var c : A = C()
c.y() // what do you expect? "Y in A" is here. I expected "Y in C"

Related topic 1&2 : IMO as soon as we have implementation in our protocols, and in this case they are 'like' classes, we need to be able to deal with these default methods implemented in protocols.

I.e. my point is if we allow protocols to be 'like' classes (to have implementations in methods), we need the tools(override,super.xxx) 'like' we have when inherit one class from another.

···

On 27.04.2016 20:10, Erica Sadun via swift-evolution wrote:

From the Swift Programming Language: /Methods on a subclass that override
the superclass’s implementation are marked with override—overriding a
method by accident, without override, is detected by the compiler as an
error. The compiler also detects methods with override that don’t actually
override any method in the superclass./

I would like to extend this cautious approach to protocols, forcing the
developer to deliberately override an implementation that’s inherited from
a protocol extension. This would prevent accidental overrides and force the
user to proactively choose to implement a version of a protocol member that
already exists in the protocol extension.

I envision this as using the same `override` keyword that’s used in class
based inheritance but extend it to protocol inheritance:

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation … }
}

type B: A {

    override required func foo () { … overrides implementation … }
}

I’d also like to bring up two related topics, although they probably should
at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two
unrelated protocols both require the same member and offer different
default implementations. Can they specify which implementation to accept or
somehow run both?

type B: A, C {
    override required func foo() { A.foo(); C.foo() }
}

Related topic 2: How can a consumer “inherit” the behavior of the default
implementation (like calling super.foo() in classes) and then extend that
behavior further. This is a bit similar to how the initialization chaining
works. I’d like to be able to call A.foo() and then add custom follow-on
behavior rather than entirely replacing the behavior.

type B: A {
    override required func foo() { A.foo(); … my custom behavior … }
}

cc’ing in Jordan who suggested a new thread on this and Doug, who has
already expressed some objections so I want him to have the opportunity to
bring that discussion here.

— E

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


(Jerome ALVES) #5

What if...

FooBar.framework defines :
public protocol A {
    func foo()
}
public type B: A {
    public func foo () {
          … implementation …
    }
}

Other module defines :
import FooBar
extension A {
    func foo() { .. default implementation … }
}

Jérôme

···

Le 27 avr. 2016 à 19:10, Erica Sadun via swift-evolution <swift-evolution@swift.org> a écrit :

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation … }
}

type B: A {

    override required func foo () { … overrides implementation … }
}


(Howard Lovatt) #6

I think that you should *always* have to write `override` when implementing
a protocol method, you can think of this as override an abstract
declaration. In particular I think the following should be enforced:

    protocol A { func a() }
    extension A { override func a() { ... } }
    struct AnA: A { override func a() { ... } }

    protocol B { func b() }
    struct AB: B { override func b() { ... } }

I think this change will work out well since it mimics what happened in
Java, originally the Java annotation `@Override` was used much like
`override` is currently used in Swift. However it was problematic and was
changed so that you always add the annotation, as shown above (in the
Swift context). One of the big advantages of this change is that the error
messages are much better (this was very noticeable in Java).

This proposal has come up before on swift-evolution, so it obviously has
some support.

···

On Thursday, 28 April 2016, Erica Sadun via swift-evolution < swift-evolution@swift.org> wrote:

From the Swift Programming Language: *Methods on a subclass that override
the superclass’s implementation are marked with override—overriding a
method by accident, without override, is detected by the compiler as an
error. The compiler also detects methods with override that don’t actually
override any method in the superclass.*

I would like to extend this cautious approach to protocols, forcing the
developer to deliberately override an implementation that’s inherited from
a protocol extension. This would prevent accidental overrides and force the
user to proactively choose to implement a version of a protocol member that
already exists in the protocol extension.

I envision this as using the same `override` keyword that’s used in class
based inheritance but extend it to protocol inheritance:

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation … }
}

type B: A {

    override required func foo () { … overrides implementation … }
}

I’d also like to bring up two related topics, although they probably
should at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two
unrelated protocols both require the same member and offer different
default implementations. Can they specify which implementation to accept or
somehow run both?

type B: A, C {
    override required func foo() { A.foo(); C.foo() }
}

Related topic 2: How can a consumer “inherit” the behavior of the default
implementation (like calling super.foo() in classes) and then extend that
behavior further. This is a bit similar to how the initialization chaining
works. I’d like to be able to call A.foo() and then add custom follow-on
behavior rather than entirely replacing the behavior.

type B: A {
    override required func foo() { A.foo(); … my custom behavior … }
}

cc’ing in Jordan who suggested a new thread on this and Doug, who has
already expressed some objections so I want him to have the opportunity to
bring that discussion here.

— E


(Howard Lovatt) #7

+1

Main part of proposal: Not sure that you need the required keyword,
overload alone has proven sufficient in Java for the same feature.

Related features: For calling default implementations in inherited
protocols I think this is a valuable feature but should be a seperate
thread.

···

On Thursday, 28 April 2016, Erica Sadun via swift-evolution < swift-evolution@swift.org> wrote:

From the Swift Programming Language: *Methods on a subclass that override
the superclass’s implementation are marked with override—overriding a
method by accident, without override, is detected by the compiler as an
error. The compiler also detects methods with override that don’t actually
override any method in the superclass.*

I would like to extend this cautious approach to protocols, forcing the
developer to deliberately override an implementation that’s inherited from
a protocol extension. This would prevent accidental overrides and force the
user to proactively choose to implement a version of a protocol member that
already exists in the protocol extension.

I envision this as using the same `override` keyword that’s used in class
based inheritance but extend it to protocol inheritance:

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation … }
}

type B: A {

    override required func foo () { … overrides implementation … }
}

I’d also like to bring up two related topics, although they probably
should at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two
unrelated protocols both require the same member and offer different
default implementations. Can they specify which implementation to accept or
somehow run both?

type B: A, C {
    override required func foo() { A.foo(); C.foo() }
}

Related topic 2: How can a consumer “inherit” the behavior of the default
implementation (like calling super.foo() in classes) and then extend that
behavior further. This is a bit similar to how the initialization chaining
works. I’d like to be able to call A.foo() and then add custom follow-on
behavior rather than entirely replacing the behavior.

type B: A {
    override required func foo() { A.foo(); … my custom behavior … }
}

cc’ing in Jordan who suggested a new thread on this and Doug, who has
already expressed some objections so I want him to have the opportunity to
bring that discussion here.

— E

--
-- Howard.


(Dave Abrahams) #8

+1!

···

on Wed Apr 27 2016, Matthew Johnson <swift-evolution@swift.org> wrote:

Sent from my iPad

On Apr 27, 2016, at 3:08 PM, Jérôme ALVES via swift-evolution > <swift-evolution@swift.org> wrote:

    What if...

    FooBar.framework defines :

    public protocol A {
    func foo()
    }
    public type B: A {
    public func foo () {
    … implementation …
    }
    }

    Other module defines :
    import FooBar

    extension A {
    func foo() { .. default implementation … }
    }

This is a good example. More generally, we should be sure that any change we
make here does not interfere with retroactive modeling.

--
Dave


(Erica Sadun) #9

From the Swift Programming Language: Methods on a subclass that override the superclass’s implementation are marked with override—overriding a method by accident, without override, is detected by the compiler as an error. The compiler also detects methods with override that don’t actually override any method in the superclass.

I would like to extend this cautious approach to protocols, forcing the developer to deliberately override an implementation that’s inherited from a protocol extension. This would prevent accidental overrides and force the user to proactively choose to implement a version of a protocol member that already exists in the protocol extension.

I envision this as using the same `override` keyword that’s used in class based inheritance but extend it to protocol inheritance:

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation … }
}

type B: A {

    override required func foo () { … overrides implementation … }
}

A couple questions about your pitch:

1) What is “required” doing there?

I threw it in not because I’m tied to it but because I wanted it to be part of the conversation.
This is a requirement from conforming to the protocol.

2) Is “override” only required when there is a default implementation of the protocol requirement, or is it required whenever you are implementing a protocol requirement?

Override is only because it is overriding the default implementation of the protocol requirement. Without that default implementation there would be no override, it would simply be satisfying the requirement.

  * If the former, it might be the case that it’s too easy to forget to add the “override” keyword (because it’s needed for some implementations of protocol requirements but not others), which undercuts the value of having it.

Forcing the override keyword makes it clear at the definition point that the story extends beyond the method or whatever to point to a default implementation that is being replaced. I *really* like having that reference in terms of both code construction (“I am doing this as a deliberate act”) with the compiler complaining otherwise, and in terms of code self documentation (“I know this was added deliberately, what default did it override?”)

  * If the latter, “override” is probably the wrong keyword because it’s not overriding anything in the common case of implementing a non-defaulted requirement.

It would be pointless if it’s just satisfying a requirement. That’s why introduced both keywords into the discussion. (And because I’m still being influenced by the “near miss” conversation.)

I’d also like to bring up two related topics, although they probably should at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two unrelated protocols both require the same member and offer different default implementations. Can they specify which implementation to accept or somehow run both?

type B: A, C {
    override required func foo() { A.foo(); C.foo() }
}

I think the right answer here is for the compiler to produce an ambiguity if you don’t implement the requirement yourself, and then solving your “related topic 2” lets you choose which implementation you want.

How do you choose which one? What syntax? For example:

required func foo = A.foo

would be the simplest approach

Related topic 2: How can a consumer “inherit” the behavior of the default implementation (like calling super.foo() in classes) and then extend that behavior further. This is a bit similar to how the initialization chaining works. I’d like to be able to call A.foo() and then add custom follow-on behavior rather than entirely replacing the behavior.

type B: A {
    override required func foo() { A.foo(); … my custom behavior … }
}

Seems totally reasonable to me. One ugly syntax: A.foo(self)(), leveraging the currying of self?

Ugly but it would pretty much do it for me. It offers an expressive way to say “Please execute the A.foo behavior using the self instance”. Does 3 still support this?

···

On Apr 27, 2016, at 12:25 PM, Douglas Gregor <dgregor@apple.com> wrote:

On Apr 27, 2016, at 10:10 AM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

cc’ing in Jordan who suggested a new thread on this and Doug, who has already expressed some objections so I want him to have the opportunity to bring that discussion here.

My objections are described here:

  http://thread.gmane.org/gmane.comp.lang.swift.devel/1799/focus=1831

Essentially, my argument is that the point of “override” (as pitched above) is to declare the user’s intent to implement a requirement. I feel that the explicit protocol conformance ("type B : A”) declares that intent, and that various common conventions (e.g., one conformance per extension, where the extension is primarily there to conform to the protocol) reinforce intent well enough for the compiler to do a good job here. I’d prefer that over another boilerplate-y keyword.

  - Doug


(Erica Sadun) #10

IMO very important questions and suggestions.

Firstly, wanted to ask about "required" keyword in your examples - do we expect to have it in meaning "implementing the protocol method" ? I'd like to have it very much.

I included it to mean “implementing a required protocol method”, providing a compile-time check that specifically addresses the same kind of issue as “near miss” detection.

* About the "override" keyword : +1 from me. We should be clear and explicit if we override method from default protocol implementation.
Right now (as I understand) we have some mess when class and protocol has the same methods. For example :

protocol A {}

extension A {
   func y() {print("Y in A")}
}

class C:A {
   func y() {
       print("Y in C")
   }
}

var c : A = C()
c.y() // what do you expect? "Y in A" is here. I expected "Y in C”

overriding a defaulted method without specific clarity of intent should raise a compiler warning. It is a likely spot where a developer may have acted without meaning to. Mandating override introduces another level of safety.

···

On Apr 27, 2016, at 12:39 PM, Vladimir.S <svabox@gmail.com> wrote:

Related topic 1&2 : IMO as soon as we have implementation in our protocols, and in this case they are 'like' classes, we need to be able to deal with these default methods implemented in protocols.

I.e. my point is if we allow protocols to be 'like' classes (to have implementations in methods), we need the tools(override,super.xxx) 'like' we have when inherit one class from another.

On 27.04.2016 20:10, Erica Sadun via swift-evolution wrote:

From the Swift Programming Language: /Methods on a subclass that override
the superclass’s implementation are marked with override—overriding a
method by accident, without override, is detected by the compiler as an
error. The compiler also detects methods with override that don’t actually
override any method in the superclass./

I would like to extend this cautious approach to protocols, forcing the
developer to deliberately override an implementation that’s inherited from
a protocol extension. This would prevent accidental overrides and force the
user to proactively choose to implement a version of a protocol member that
already exists in the protocol extension.

I envision this as using the same `override` keyword that’s used in class
based inheritance but extend it to protocol inheritance:

protocol A {
   func foo()
}

extension A {
   func foo() { .. default implementation … }
}

type B: A {

   override required func foo () { … overrides implementation … }
}

I’d also like to bring up two related topics, although they probably should
at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two
unrelated protocols both require the same member and offer different
default implementations. Can they specify which implementation to accept or
somehow run both?

type B: A, C {
   override required func foo() { A.foo(); C.foo() }
}

Related topic 2: How can a consumer “inherit” the behavior of the default
implementation (like calling super.foo() in classes) and then extend that
behavior further. This is a bit similar to how the initialization chaining
works. I’d like to be able to call A.foo() and then add custom follow-on
behavior rather than entirely replacing the behavior.

type B: A {
   override required func foo() { A.foo(); … my custom behavior … }
}

cc’ing in Jordan who suggested a new thread on this and Doug, who has
already expressed some objections so I want him to have the opportunity to
bring that discussion here.

— E

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


(Erica Sadun) #11

What if...

FooBar.framework defines :
public protocol A {
    func foo()
}
public type B: A {
    public func foo () {
          … implementation …
    }
}

Other module defines :
import FooBar
extension A {
    func foo() { .. default implementation … }
}

Under these circumstances because of the mandatory import statement, there is no difference between the extension being defined in or outside the module, so long as the other module access is public. If it is not visible to the conforming protocol, there is no issue.

Conflicts of multiple protocol default implementations would need to be resolved exactly the same way as previously discussed, the only difference being namespacing:

required foo = OtherModule.A.foo

— E

···

On Apr 27, 2016, at 2:08 PM, Jérôme ALVES <j.alves@me.com> wrote:

Jérôme

Le 27 avr. 2016 à 19:10, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation … }
}

type B: A {

    override required func foo () { … overrides implementation … }
}


(Matthew Johnson) #12

What if...

FooBar.framework defines :
public protocol A {
    func foo()
}
public type B: A {
    public func foo () {
          … implementation …
    }
}

Other module defines :
import FooBar
extension A {
    func foo() { .. default implementation … }
}

This is a good example. More generally, we should be sure that any change we make here does not interfere with retroactive modeling.

···

Sent from my iPad

On Apr 27, 2016, at 3:08 PM, Jérôme ALVES via swift-evolution <swift-evolution@swift.org> wrote:

Jérôme

Le 27 avr. 2016 à 19:10, Erica Sadun via swift-evolution <swift-evolution@swift.org> a écrit :

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation … }
}

type B: A {

    override required func foo () { … overrides implementation … }
}

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


(Goffredo Marocchi) #13

I still think that the type of the reference governs which code runs feels so vestigial of a part of C++ I always disliked (default if you are not using the virtual keyword). Especially dealing with protocols that have generally always be interpreted to be abstract API contracts.

I would say to have dynamic dispatching to be default unless the compiler knows there is no sideffect (no difference if an instance is referred through a certain reference type or another) or the used specified a a keyword in the public protocol interface.

[[iOS messageWithData:ideas] broadcast]

···

On 27 Apr 2016, at 21:17, Tod Cunningham via swift-evolution <swift-evolution@swift.org> wrote:

Having to specify override to override the implementation of protocol leads one further down the path that the protocol’s implementation is actually being overridden. However, currently that is not the case. If the protocol’s definition was actually being overridden, I think you would have a good case. But swift, as it exists today, will still call the protocol’s default implementation if accessed through the protocol type. So it isn’t really overriding the implementation of the protocol:

For example:

protocol Test {

}

extension Test {

   var hello: String {

       return "hello"

   }

}

class A: Test {

}

class B: Test {

   var hello: String {

       return "see ya"

   }

}

print( A().hello ) // hello

print( B().hello ) // see ya

let test1: Test = A()

print( test1.hello ) // hello

let test2: Test = B()

print( test2.hello ) // hello <== not "see ya"

Thanks,

Tod Cunningham

From: <swift-evolution-bounces@swift.org<mailto:swift-evolution-bounces@swift.org>> on behalf of Erica Sadun via swift-evolution <swift-evolution@swift.org<mailto:swift-evolution@swift.org>>
Reply-To: Erica Sadun <erica@ericasadun.com<mailto:erica@ericasadun.com>>
Date: Wednesday, April 27, 2016 at 1:10 PM
To: swift-evolution <swift-evolution@swift.org<mailto:swift-evolution@swift.org>>, Jordan Rose <jordan_rose@apple.com<mailto:jordan_rose@apple.com>>, Douglas Gregor <dgregor@apple.com<mailto:dgregor@apple.com>>
Subject: [swift-evolution] [Pitch] Requiring proactive overrides for default protocol implementations.

From the Swift Programming Language: Methods on a subclass that override the superclass’s implementation are marked with override—overriding a method by accident, without override, is detected by the compiler as an error. The compiler also detects methods with override that don’t actually override any method in the superclass.

I would like to extend this cautious approach to protocols, forcing the developer to deliberately override an implementation that’s inherited from a protocol extension. This would prevent accidental overrides and force the user to proactively choose to implement a version of a protocol member that already exists in the protocol extension.

I envision this as using the same `override` keyword that’s used in class based inheritance but extend it to protocol inheritance:

protocol A {
   func foo()
}

extension A {
   func foo() { .. default implementation … }
}

type B: A {

   override required func foo () { … overrides implementation … }
}

I’d also like to bring up two related topics, although they probably should at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two unrelated protocols both require the same member and offer different default implementations. Can they specify which implementation to accept or somehow run both?

type B: A, C {
   override required func foo() { A.foo(); C.foo() }
}

Related topic 2: How can a consumer “inherit” the behavior of the default implementation (like calling super.foo() in classes) and then extend that behavior further. This is a bit similar to how the initialization chaining works. I’d like to be able to call A.foo() and then add custom follow-on behavior rather than entirely replacing the behavior.

type B: A {
   override required func foo() { A.foo(); … my custom behavior … }
}

cc’ing in Jordan who suggested a new thread on this and Doug, who has already expressed some objections so I want him to have the opportunity to bring that discussion here.

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


(Josh Parmenter) #14

I think that you should *always* have to write `override` when implementing a protocol method, you can think of this as override an abstract declaration. In particular I think the following should be enforced:

    protocol A { func a() }
    extension A { override func a() { ... } }
    struct AnA: A { override func a() { ... } }

    protocol B { func b() }
    struct AB: B { override func b() { ... } }

I'm rather new to the list - but I would like to say that I agree with this. I think it gives clarity both to code readability, and for learning the language.
Best
Josh

I think this change will work out well since it mimics what happened in Java, originally the Java annotation `@Override` was used much like `override` is currently used in Swift. However it was problematic and was changed so that you always add the annotation, as shown above (in the Swift context). One of the big advantages of this change is that the error messages are much better (this was very noticeable in Java).

This proposal has come up before on swift-evolution, so it obviously has some support.

From the Swift Programming Language: Methods on a subclass that override the superclass's implementation are marked with override-overriding a method by accident, without override, is detected by the compiler as an error. The compiler also detects methods with override that don't actually override any method in the superclass.

I would like to extend this cautious approach to protocols, forcing the developer to deliberately override an implementation that's inherited from a protocol extension. This would prevent accidental overrides and force the user to proactively choose to implement a version of a protocol member that already exists in the protocol extension.

I envision this as using the same `override` keyword that's used in class based inheritance but extend it to protocol inheritance:

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation ... }
}

type B: A {

    override required func foo () { ... overrides implementation ... }
}

I'd also like to bring up two related topics, although they probably should at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two unrelated protocols both require the same member and offer different default implementations. Can they specify which implementation to accept or somehow run both?

type B: A, C {
    override required func foo() { A.foo(); C.foo() }
}

Related topic 2: How can a consumer "inherit" the behavior of the default implementation (like calling super.foo() in classes) and then extend that behavior further. This is a bit similar to how the initialization chaining works. I'd like to be able to call A.foo() and then add custom follow-on behavior rather than entirely replacing the behavior.

type B: A {
    override required func foo() { A.foo(); ... my custom behavior ... }
}

cc'ing in Jordan who suggested a new thread on this and Doug, who has already expressed some objections so I want him to have the opportunity to bring that discussion here.

- E

···

On Apr 27, 2016, at 17:23, Howard Lovatt via swift-evolution <swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:
On Thursday, 28 April 2016, Erica Sadun via swift-evolution <swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org<mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Tod Cunningham) #15

I think it would be odd and confusing to always have to use override when implementing protocol methods (especially protocol methods without default implementations). To me override is telling me that there is another implementation, and I am for lack of a better word overriding that implementation. However, for a protocol w/o a default implementation, there is no implementation. You aren’t overriding anything. You are just conforming to a signature. Now protocol’s with default implementations there could be a case made for using override. Expect Swift current implementation doesn't really override the default implementation, as shown in my example. The other issues would be if I am overriding something, I would expect to be able to execute the default implementation from within my override.

It might be nice to have some syntax that would identify the protocol that is being implemented at the point of the implementation. For example (although I don't like this syntax):
   func (protocolname1, protocolname2) commonmethod() -> Void { .. the implementation.. }

- Tod Cunningham

···

________________________________________
From: swift-evolution-bounces@swift.org <swift-evolution-bounces@swift.org> on behalf of Josh Parmenter via swift-evolution <swift-evolution@swift.org>
Sent: Wednesday, April 27, 2016 8:27 PM
To: Howard Lovatt
Cc: swift-evolution
Subject: Re: [swift-evolution] [Pitch] Requiring proactive overrides for default protocol implementations.

On Apr 27, 2016, at 17:23, Howard Lovatt via swift-evolution <swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:

I think that you should *always* have to write `override` when implementing a protocol method, you can think of this as override an abstract declaration. In particular I think the following should be enforced:

    protocol A { func a() }
    extension A { override func a() { ... } }
    struct AnA: A { override func a() { ... } }

    protocol B { func b() }
    struct AB: B { override func b() { ... } }

I'm rather new to the list - but I would like to say that I agree with this. I think it gives clarity both to code readability, and for learning the language.
Best
Josh

I think this change will work out well since it mimics what happened in Java, originally the Java annotation `@Override` was used much like `override` is currently used in Swift. However it was problematic and was changed so that you always add the annotation, as shown above (in the Swift context). One of the big advantages of this change is that the error messages are much better (this was very noticeable in Java).

This proposal has come up before on swift-evolution, so it obviously has some support.

On Thursday, 28 April 2016, Erica Sadun via swift-evolution <swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:

From the Swift Programming Language: Methods on a subclass that override the superclass's implementation are marked with override-overriding a method by accident, without override, is detected by the compiler as an error. The compiler also detects methods with override that don't actually override any method in the superclass.

I would like to extend this cautious approach to protocols, forcing the developer to deliberately override an implementation that's inherited from a protocol extension. This would prevent accidental overrides and force the user to proactively choose to implement a version of a protocol member that already exists in the protocol extension.

I envision this as using the same `override` keyword that's used in class based inheritance but extend it to protocol inheritance:

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation ... }
}

type B: A {

    override required func foo () { ... overrides implementation ... }
}

I'd also like to bring up two related topics, although they probably should at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two unrelated protocols both require the same member and offer different default implementations. Can they specify which implementation to accept or somehow run both?

type B: A, C {
    override required func foo() { A.foo(); C.foo() }
}

Related topic 2: How can a consumer "inherit" the behavior of the default implementation (like calling super.foo() in classes) and then extend that behavior further. This is a bit similar to how the initialization chaining works. I'd like to be able to call A.foo() and then add custom follow-on behavior rather than entirely replacing the behavior.

type B: A {
    override required func foo() { A.foo(); ... my custom behavior ... }
}

cc'ing in Jordan who suggested a new thread on this and Doug, who has already expressed some objections so I want him to have the opportunity to bring that discussion here.

- E
_______________________________________________
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


(Howard Lovatt) #16

@Tod,

This was a concern when Java changed the behaviour of `@Override`, but it
didn't pan out. Everyone, even those with reservations, grew to like the
new behaviour. I think the much improved error messages from the compiler
helped, e.g.:

    protocol ViewObserver {
        func append(observer observer: Observer)
        func remove(observer observer: Observer)
        func removeAll()
    }
    struct AViewObserver: ViewObserver {
        func apend(observer observer: Observer) {
            ...
        }
        func remove(observer observer: Observer) {
            ...
        }
        func removeAll() {
            ...
        }
    }

The only error you get at present with the above is that `AViewObserver`
does not conform to `ViewObserver`, it doesn't tell you why. With the
change the compiler would highlight that `apend` doesn't override `append`
:(.

  -- Howard.

···

On 28 April 2016 at 11:17, Tod Cunningham <tcunningham@vectorform.com> wrote:

I think it would be odd and confusing to always have to use override when
implementing protocol methods (especially protocol methods without default
implementations). To me override is telling me that there is another
implementation, and I am for lack of a better word overriding that
implementation. However, for a protocol w/o a default implementation,
there is no implementation. You aren’t overriding anything. You are just
conforming to a signature. Now protocol’s with default implementations
there could be a case made for using override. Expect Swift current
implementation doesn't really override the default implementation, as shown
in my example. The other issues would be if I am overriding something, I
would expect to be able to execute the default implementation from within
my override.

It might be nice to have some syntax that would identify the protocol that
is being implemented at the point of the implementation. For example
(although I don't like this syntax):
   func (protocolname1, protocolname2) commonmethod() -> Void { .. the
implementation.. }

- Tod Cunningham
________________________________________
From: swift-evolution-bounces@swift.org <swift-evolution-bounces@swift.org>
on behalf of Josh Parmenter via swift-evolution <swift-evolution@swift.org
>
Sent: Wednesday, April 27, 2016 8:27 PM
To: Howard Lovatt
Cc: swift-evolution
Subject: Re: [swift-evolution] [Pitch] Requiring proactive overrides for
default protocol implementations.

On Apr 27, 2016, at 17:23, Howard Lovatt via swift-evolution < > swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:

I think that you should *always* have to write `override` when
implementing a protocol method, you can think of this as override an
abstract declaration. In particular I think the following should be
enforced:

    protocol A { func a() }
    extension A { override func a() { ... } }
    struct AnA: A { override func a() { ... } }

    protocol B { func b() }
    struct AB: B { override func b() { ... } }

I'm rather new to the list - but I would like to say that I agree with
this. I think it gives clarity both to code readability, and for learning
the language.
Best
Josh

I think this change will work out well since it mimics what happened in
Java, originally the Java annotation `@Override` was used much like
`override` is currently used in Swift. However it was problematic and was
changed so that you always add the annotation, as shown above (in the Swift
context). One of the big advantages of this change is that the error
messages are much better (this was very noticeable in Java).

This proposal has come up before on swift-evolution, so it obviously has
some support.

On Thursday, 28 April 2016, Erica Sadun via swift-evolution < > swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:
From the Swift Programming Language: Methods on a subclass that override
the superclass's implementation are marked with override-overriding a
method by accident, without override, is detected by the compiler as an
error. The compiler also detects methods with override that don't actually
override any method in the superclass.

I would like to extend this cautious approach to protocols, forcing the
developer to deliberately override an implementation that's inherited from
a protocol extension. This would prevent accidental overrides and force the
user to proactively choose to implement a version of a protocol member that
already exists in the protocol extension.

I envision this as using the same `override` keyword that's used in class
based inheritance but extend it to protocol inheritance:

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation ... }
}

type B: A {

    override required func foo () { ... overrides implementation ... }
}

I'd also like to bring up two related topics, although they probably
should at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two
unrelated protocols both require the same member and offer different
default implementations. Can they specify which implementation to accept or
somehow run both?

type B: A, C {
    override required func foo() { A.foo(); C.foo() }
}

Related topic 2: How can a consumer "inherit" the behavior of the default
implementation (like calling super.foo() in classes) and then extend that
behavior further. This is a bit similar to how the initialization chaining
works. I'd like to be able to call A.foo() and then add custom follow-on
behavior rather than entirely replacing the behavior.

type B: A {
    override required func foo() { A.foo(); ... my custom behavior ... }
}

cc'ing in Jordan who suggested a new thread on this and Doug, who has
already expressed some objections so I want him to have the opportunity to
bring that discussion here.

- E
_______________________________________________
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


(Douglas Gregor) #17

From the Swift Programming Language: Methods on a subclass that override the superclass’s implementation are marked with override—overriding a method by accident, without override, is detected by the compiler as an error. The compiler also detects methods with override that don’t actually override any method in the superclass.

I would like to extend this cautious approach to protocols, forcing the developer to deliberately override an implementation that’s inherited from a protocol extension. This would prevent accidental overrides and force the user to proactively choose to implement a version of a protocol member that already exists in the protocol extension.

I envision this as using the same `override` keyword that’s used in class based inheritance but extend it to protocol inheritance:

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation … }
}

type B: A {

    override required func foo () { … overrides implementation … }
}

A couple questions about your pitch:

1) What is “required” doing there?

I threw it in not because I’m tied to it but because I wanted it to be part of the conversation.
This is a requirement from conforming to the protocol.

Ah. Note that this isn’t *quite* the meaning of “required” for initializers of classes (where it means “my subclasses must override this”), but in practice it’s basically the only reason why anyone uses “required” for initializers.

2) Is “override” only required when there is a default implementation of the protocol requirement, or is it required whenever you are implementing a protocol requirement?

Override is only because it is overriding the default implementation of the protocol requirement. Without that default implementation there would be no override, it would simply be satisfying the requirement.

For me, this doesn’t provide additional value of “required”: i.e., the value of having a keyword here is in telling me that I failed to implement a requirement when I’ve clearly said that I wanted to implement a requirement. Whether there was a default there or not isn’t really very interesting. Plus, a default could be added later to a requirement that I implement: that change has zero impact on how my code works (before or after), but now I’d be require to add an “override” keyword when I recompile.

Contrast that with classes: if you recompile against a new version of a library and the compiler tells you that you need to add “override”, it’s serious because the semantics of your program will change if you’re now overriding something that you weren’t before.

  * If the former, it might be the case that it’s too easy to forget to add the “override” keyword (because it’s needed for some implementations of protocol requirements but not others), which undercuts the value of having it.

Forcing the override keyword makes it clear at the definition point that the story extends beyond the method or whatever to point to a default implementation that is being replaced. I *really* like having that reference in terms of both code construction (“I am doing this as a deliberate act”) with the compiler complaining otherwise, and in terms of code self documentation (“I know this was added deliberately, what default did it override?”)

I see the former (“I am doing this as a deliberate act”) as a very common complaint; the latter not nearly as much. What motivates that? And does it justify adding a *second* keyword to these declarations?

I’d also like to bring up two related topics, although they probably should at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two unrelated protocols both require the same member and offer different default implementations. Can they specify which implementation to accept or somehow run both?

type B: A, C {
    override required func foo() { A.foo(); C.foo() }
}

I think the right answer here is for the compiler to produce an ambiguity if you don’t implement the requirement yourself, and then solving your “related topic 2” lets you choose which implementation you want.

How do you choose which one? What syntax? For example:

required func foo = A.foo

would be the simplest approach

type B: A, C {
  override required func foo() { A.foo(self)() }
}

Related topic 2: How can a consumer “inherit” the behavior of the default implementation (like calling super.foo() in classes) and then extend that behavior further. This is a bit similar to how the initialization chaining works. I’d like to be able to call A.foo() and then add custom follow-on behavior rather than entirely replacing the behavior.

type B: A {
    override required func foo() { A.foo(); … my custom behavior … }
}

Seems totally reasonable to me. One ugly syntax: A.foo(self)(), leveraging the currying of self?

Ugly but it would pretty much do it for me. It offers an expressive way to say “Please execute the A.foo behavior using the self instance”. Does 3 still support this?

Probably not? I actually don’t know :wink:

  - Doug

···

On Apr 27, 2016, at 12:31 PM, Erica Sadun <erica@ericasadun.com> wrote:
On Apr 27, 2016, at 12:25 PM, Douglas Gregor <dgregor@apple.com <mailto:dgregor@apple.com>> wrote:

On Apr 27, 2016, at 10:10 AM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:


(L Mihalkovic) #18

Inline

Regards
(From mobile)

From the Swift Programming Language: Methods on a subclass that override the superclass’s implementation are marked with override—overriding a method by accident, without override, is detected by the compiler as an error. The compiler also detects methods with override that don’t actually override any method in the superclass.

I would like to extend this cautious approach to protocols, forcing the developer to deliberately override an implementation that’s inherited from a protocol extension. This would prevent accidental overrides and force the user to proactively choose to implement a version of a protocol member that already exists in the protocol extension.

I envision this as using the same `override` keyword that’s used in class based inheritance but extend it to protocol inheritance:

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation … }
}

type B: A {

    override required func foo () { … overrides implementation … }
}

A couple questions about your pitch:

1) What is “required” doing there?

I threw it in not because I’m tied to it but because I wanted it to be part of the conversation.
This is a requirement from conforming to the protocol.

2) Is “override” only required when there is a default implementation of the protocol requirement, or is it required whenever you are implementing a protocol requirement?

Override is only because it is overriding the default implementation of the protocol requirement. Without that default implementation there would be no override, it would simply be satisfying the requirement.

  * If the former, it might be the case that it’s too easy to forget to add the “override” keyword (because it’s needed for some implementations of protocol requirements but not others), which undercuts the value of having it.

Forcing the override keyword makes it clear at the definition point that the story extends beyond the method or whatever to point to a default implementation that is being replaced. I *really* like having that reference in terms of both code construction (“I am doing this as a deliberate act”) with the compiler complaining otherwise, and in terms of code self documentation (“I know this was added deliberately, what default did it override?”)

  * If the latter, “override” is probably the wrong keyword because it’s not overriding anything in the common case of implementing a non-defaulted requirement.

It would be pointless if it’s just satisfying a requirement. That’s why introduced both keywords into the discussion. (And because I’m still being influenced by the “near miss” conversation.)

One could always argue that should protocol definitions ever be allowed to contain default implementations ala-java default methods, the distinction between former and latter would go away, and it would be happy anticipation to have mandated *override* all along in all cases, ensuring that future default methods would not accidentally take precedence of current code or wind up being treated differently than other overrides.

···

On Apr 27, 2016, at 9:31 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

On Apr 27, 2016, at 12:25 PM, Douglas Gregor <dgregor@apple.com> wrote:

On Apr 27, 2016, at 10:10 AM, Erica Sadun <erica@ericasadun.com> wrote:

I’d also like to bring up two related topics, although they probably should at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two unrelated protocols both require the same member and offer different default implementations. Can they specify which implementation to accept or somehow run both?

type B: A, C {
    override required func foo() { A.foo(); C.foo() }
}

I think the right answer here is for the compiler to produce an ambiguity if you don’t implement the requirement yourself, and then solving your “related topic 2” lets you choose which implementation you want.

How do you choose which one? What syntax? For example:

required func foo = A.foo

would be the simplest approach

Related topic 2: How can a consumer “inherit” the behavior of the default implementation (like calling super.foo() in classes) and then extend that behavior further. This is a bit similar to how the initialization chaining works. I’d like to be able to call A.foo() and then add custom follow-on behavior rather than entirely replacing the behavior.

type B: A {
    override required func foo() { A.foo(); … my custom behavior … }
}

Seems totally reasonable to me. One ugly syntax: A.foo(self)(), leveraging the currying of self?

Ugly but it would pretty much do it for me. It offers an expressive way to say “Please execute the A.foo behavior using the self instance”. Does 3 still support this?

cc’ing in Jordan who suggested a new thread on this and Doug, who has already expressed some objections so I want him to have the opportunity to bring that discussion here.

My objections are described here:

  http://thread.gmane.org/gmane.comp.lang.swift.devel/1799/focus=1831

Essentially, my argument is that the point of “override” (as pitched above) is to declare the user’s intent to implement a requirement. I feel that the explicit protocol conformance ("type B : A”) declares that intent, and that various common conventions (e.g., one conformance per extension, where the extension is primarily there to conform to the protocol) reinforce intent well enough for the compiler to do a good job here. I’d prefer that over another boilerplate-y keyword.

  - Doug

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


(Charles Srstka) #19

I would prefer the “override” only apply to methods that already had default protocol implementations, because then it could help avoid the mistake of overriding a default implementation that you didn’t realize was there, thinking that this was a method that you needed to supply.

Charles

···

On Apr 27, 2016, at 8:26 PM, Howard Lovatt via swift-evolution <swift-evolution@swift.org> wrote:

@Tod,

This was a concern when Java changed the behaviour of `@Override`, but it didn't pan out. Everyone, even those with reservations, grew to like the new behaviour. I think the much improved error messages from the compiler helped, e.g.:

    protocol ViewObserver {
        func append(observer observer: Observer)
        func remove(observer observer: Observer)
        func removeAll()
    }
    struct AViewObserver: ViewObserver {
        func apend(observer observer: Observer) {
            ...
        }
        func remove(observer observer: Observer) {
            ...
        }
        func removeAll() {
            ...
        }
    }

The only error you get at present with the above is that `AViewObserver` does not conform to `ViewObserver`, it doesn't tell you why. With the change the compiler would highlight that `apend` doesn't override `append` :(.

  -- Howard.

On 28 April 2016 at 11:17, Tod Cunningham <tcunningham@vectorform.com <mailto:tcunningham@vectorform.com>> wrote:
I think it would be odd and confusing to always have to use override when implementing protocol methods (especially protocol methods without default implementations). To me override is telling me that there is another implementation, and I am for lack of a better word overriding that implementation. However, for a protocol w/o a default implementation, there is no implementation. You aren’t overriding anything. You are just conforming to a signature. Now protocol’s with default implementations there could be a case made for using override. Expect Swift current implementation doesn't really override the default implementation, as shown in my example. The other issues would be if I am overriding something, I would expect to be able to execute the default implementation from within my override.

It might be nice to have some syntax that would identify the protocol that is being implemented at the point of the implementation. For example (although I don't like this syntax):
   func (protocolname1, protocolname2) commonmethod() -> Void { .. the implementation.. }

- Tod Cunningham
________________________________________
From: swift-evolution-bounces@swift.org <mailto:swift-evolution-bounces@swift.org> <swift-evolution-bounces@swift.org <mailto:swift-evolution-bounces@swift.org>> on behalf of Josh Parmenter via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>
Sent: Wednesday, April 27, 2016 8:27 PM
To: Howard Lovatt
Cc: swift-evolution
Subject: Re: [swift-evolution] [Pitch] Requiring proactive overrides for default protocol implementations.

On Apr 27, 2016, at 17:23, Howard Lovatt via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org><mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> wrote:

I think that you should *always* have to write `override` when implementing a protocol method, you can think of this as override an abstract declaration. In particular I think the following should be enforced:

    protocol A { func a() }
    extension A { override func a() { ... } }
    struct AnA: A { override func a() { ... } }

    protocol B { func b() }
    struct AB: B { override func b() { ... } }

I'm rather new to the list - but I would like to say that I agree with this. I think it gives clarity both to code readability, and for learning the language.
Best
Josh

I think this change will work out well since it mimics what happened in Java, originally the Java annotation `@Override` was used much like `override` is currently used in Swift. However it was problematic and was changed so that you always add the annotation, as shown above (in the Swift context). One of the big advantages of this change is that the error messages are much better (this was very noticeable in Java).

This proposal has come up before on swift-evolution, so it obviously has some support.

On Thursday, 28 April 2016, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org><mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> wrote:
From the Swift Programming Language: Methods on a subclass that override the superclass's implementation are marked with override-overriding a method by accident, without override, is detected by the compiler as an error. The compiler also detects methods with override that don't actually override any method in the superclass.

I would like to extend this cautious approach to protocols, forcing the developer to deliberately override an implementation that's inherited from a protocol extension. This would prevent accidental overrides and force the user to proactively choose to implement a version of a protocol member that already exists in the protocol extension.

I envision this as using the same `override` keyword that's used in class based inheritance but extend it to protocol inheritance:

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation ... }
}

type B: A {

    override required func foo () { ... overrides implementation ... }
}

I'd also like to bring up two related topics, although they probably should at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two unrelated protocols both require the same member and offer different default implementations. Can they specify which implementation to accept or somehow run both?

type B: A, C {
    override required func foo() { A.foo(); C.foo() }
}

Related topic 2: How can a consumer "inherit" the behavior of the default implementation (like calling super.foo() in classes) and then extend that behavior further. This is a bit similar to how the initialization chaining works. I'd like to be able to call A.foo() and then add custom follow-on behavior rather than entirely replacing the behavior.

type B: A {
    override required func foo() { A.foo(); ... my custom behavior ... }
}

cc'ing in Jordan who suggested a new thread on this and Doug, who has already expressed some objections so I want him to have the opportunity to bring that discussion here.

- E
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org><mailto: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
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Wallacy) #20

I wrote a proposal few weeks ago about "Complete Composition Model" in
Swift, but still not finish (too many details)...

In my proposal, i thought about the problem in this topic. However after
thinking more generally, I found it best to solve in other direction:

- Every time one default protocol implementations is provide, the generated
Header will include de "default" at beginner.
-- No source code change, the change is just for generated header. For
Frameworks and libs, will apear em the "final generated header" of course.
But for changes in our own module, will apear on xcode generated header,
auto complete, detail tab, changes in color code, etc...

The ideia is provide a way to "see" more easily if a method has a default
implementation, but does not change de code itself because this
implementation can be made any time by someone, without break anything.

- Every time we "re implement" one default protocol implementation for
other module with already have this "default" keyword, we need to provide a
"implements" (or require) keyword to avoid a compiler warning.
-- Do not put a keyword to tell if you are implementing a protocol
requirement is not exactly a error, but can be considered if you previously
know about default implementation. No keyword is needed if no default
implementations is provided, but can be used for clarify the intention.

- For or own module, xcode / auto-complete, detail tab, color code, etc...
can tel you about the "has default implementation" without the warning.

At end of the day, there no need to any noise to tell something about
default implementation, just a little help.

If we make "everything explicit", inference type will be abolished.
Sometimes we can count on to develop "look the metadatas/interfaces"

If someone wants I can post the proposal I have written tomorrow.

···

Em qui, 28 de abr de 2016 às 02:08, Charles Srstka via swift-evolution < swift-evolution@swift.org> escreveu:

I would prefer the “override” only apply to methods that already had
default protocol implementations, because then it could help avoid the
mistake of overriding a default implementation that you didn’t realize was
there, thinking that this was a method that you needed to supply.

Charles

On Apr 27, 2016, at 8:26 PM, Howard Lovatt via swift-evolution < > swift-evolution@swift.org> wrote:

@Tod,

This was a concern when Java changed the behaviour of `@Override`, but it
didn't pan out. Everyone, even those with reservations, grew to like the
new behaviour. I think the much improved error messages from the compiler
helped, e.g.:

    protocol ViewObserver {
        func append(observer observer: Observer)
        func remove(observer observer: Observer)
        func removeAll()
    }
    struct AViewObserver: ViewObserver {
        func apend(observer observer: Observer) {
            ...
        }
        func remove(observer observer: Observer) {
            ...
        }
        func removeAll() {
            ...
        }
    }

The only error you get at present with the above is that `AViewObserver`
does not conform to `ViewObserver`, it doesn't tell you why. With the
change the compiler would highlight that `apend` doesn't override `append`
:(.

  -- Howard.

On 28 April 2016 at 11:17, Tod Cunningham <tcunningham@vectorform.com> > wrote:

I think it would be odd and confusing to always have to use override when
implementing protocol methods (especially protocol methods without default
implementations). To me override is telling me that there is another
implementation, and I am for lack of a better word overriding that
implementation. However, for a protocol w/o a default implementation,
there is no implementation. You aren’t overriding anything. You are just
conforming to a signature. Now protocol’s with default implementations
there could be a case made for using override. Expect Swift current
implementation doesn't really override the default implementation, as shown
in my example. The other issues would be if I am overriding something, I
would expect to be able to execute the default implementation from within
my override.

It might be nice to have some syntax that would identify the protocol
that is being implemented at the point of the implementation. For example
(although I don't like this syntax):
   func (protocolname1, protocolname2) commonmethod() -> Void { .. the
implementation.. }

- Tod Cunningham
________________________________________
From: swift-evolution-bounces@swift.org <
swift-evolution-bounces@swift.org> on behalf of Josh Parmenter via
swift-evolution <swift-evolution@swift.org>
Sent: Wednesday, April 27, 2016 8:27 PM
To: Howard Lovatt
Cc: swift-evolution
Subject: Re: [swift-evolution] [Pitch] Requiring proactive overrides for
default protocol implementations.

On Apr 27, 2016, at 17:23, Howard Lovatt via swift-evolution < >> swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:

I think that you should *always* have to write `override` when
implementing a protocol method, you can think of this as override an
abstract declaration. In particular I think the following should be
enforced:

    protocol A { func a() }
    extension A { override func a() { ... } }
    struct AnA: A { override func a() { ... } }

    protocol B { func b() }
    struct AB: B { override func b() { ... } }

I'm rather new to the list - but I would like to say that I agree with
this. I think it gives clarity both to code readability, and for learning
the language.
Best
Josh

I think this change will work out well since it mimics what happened in
Java, originally the Java annotation `@Override` was used much like
`override` is currently used in Swift. However it was problematic and was
changed so that you always add the annotation, as shown above (in the Swift
context). One of the big advantages of this change is that the error
messages are much better (this was very noticeable in Java).

This proposal has come up before on swift-evolution, so it obviously has
some support.

On Thursday, 28 April 2016, Erica Sadun via swift-evolution < >> swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:
From the Swift Programming Language: Methods on a subclass that override
the superclass's implementation are marked with override-overriding a
method by accident, without override, is detected by the compiler as an
error. The compiler also detects methods with override that don't actually
override any method in the superclass.

I would like to extend this cautious approach to protocols, forcing the
developer to deliberately override an implementation that's inherited from
a protocol extension. This would prevent accidental overrides and force the
user to proactively choose to implement a version of a protocol member that
already exists in the protocol extension.

I envision this as using the same `override` keyword that's used in class
based inheritance but extend it to protocol inheritance:

protocol A {
    func foo()
}

extension A {
    func foo() { .. default implementation ... }
}

type B: A {

    override required func foo () { ... overrides implementation ... }
}

I'd also like to bring up two related topics, although they probably
should at some point move to their own thread if they have any legs:

Related topic 1: How should a consumer handle a situation where two
unrelated protocols both require the same member and offer different
default implementations. Can they specify which implementation to accept or
somehow run both?

type B: A, C {
    override required func foo() { A.foo(); C.foo() }
}

Related topic 2: How can a consumer "inherit" the behavior of the default
implementation (like calling super.foo() in classes) and then extend that
behavior further. This is a bit similar to how the initialization chaining
works. I'd like to be able to call A.foo() and then add custom follow-on
behavior rather than entirely replacing the behavior.

type B: A {
    override required func foo() { A.foo(); ... my custom behavior ... }
}

cc'ing in Jordan who suggested a new thread on this and Doug, who has
already expressed some objections so I want him to have the opportunity to
bring that discussion here.

- E
_______________________________________________
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

_______________________________________________
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