open/public protocol with not overridable default implementation in the future?


(Adrian Zubarev) #1

I always wanted a way to make some protocol default implementations not overridable. Now Swift 3 got open vs. public behavior for classes. (Hopefully the inconsistency will be fixed soon and we’ll get open protocols as well.)

Imagine this scenario with open/public protocols.

// Module A
// `open protocol` means that in a diff. module I'll
// be able to conform to that protocol
open protocol Proto {}

extension Proto {
     // shouldn't this mean that the variable is not overridable
     // from a different module? :slight_smile:
     public var foo: Int { return 42 }
}

// Module B
struct A : Proto {
    // can I or can I not override `foo` from here?
}
I wonder if my thinking is correct here, or do we need something else to make extensions with default implementation to be fixed and not overridable?

···

--
Adrian Zubarev
Sent with Airmail


Constrain protocol usage outside the module
(Brent Royal-Gordon) #2

I always wanted a way to make some protocol default implementations not overridable. Now Swift 3 got open vs. public behavior for classes. (Hopefully the inconsistency will be fixed soon and we’ll get open protocols as well.)

Imagine this scenario with open/public protocols.

// Module A
// `open protocol` means that in a diff. module I'll
// be able to conform to that protocol
open protocol Proto {}

extension Proto {
     // shouldn't this mean that the variable is not overridable
     // from a different module? :slight_smile:
     public var foo: Int { return 42 }
}

// Module B
struct A : Proto {
    // can I or can I not override `foo` from here?
}

I wonder if my thinking is correct here, or do we need something else to make extensions with default implementation to be fixed and not overridable?

Currently, a declaration of `A.foo` would not *override* `Proto.foo`, it would *shadow* it. Using `foo` on a variable of type `Proto` will always use `Proto`'s implementation. That's why `A.foo`'s declaration will not have the `override` keyword. It's a subtle distinction, but a really important one—if you're expecting a call to `Proto.foo` to instead go to `A.foo`, you're gonna have a bad time.

Personally, I think this is a bad idea, and I'd like to see the compiler reject conformances which cause visible shadowing. But that's a different story. As long as we're allowing this shadowing to pass unremarked, it makes sense that `public` wouldn't prevent it.

···

--
Brent Royal-Gordon
Architechies