[swift-evolution] Renaming for Protocol Conformance

Karl razielim at gmail.com
Tue Aug 23 00:39:47 CDT 2016


> On 23 Aug 2016, at 06:59, Jonathan Hull via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Hi everyone,
> 
> We talked about this before when we were discussing mixins, and there seemed to be generally positive feelings towards it as a feature for the future.  I am fairly certain this affects the ABI though, so I thought I would bring it up now.
> 
> If two protocols have methods/properties with the same name, but different signatures, we need a way to distinguish between them when attempting to conform to both.
> 
> 	protocol A {
> 		var x:Int {get set}
> 	}
> 
> 	protocol B {
> 		var x:Double {get set}
> 	}
> 
> One possibility is to allow a struct/class/enum to conform to the protocol while renaming one (or both) of the clashing methods:
> 
> 	struct C: A,B {
> 		var x:Int
> 		var y:Double implements B.x
> 	}
> 
> The conforming method/property would still have to have the same signature, but could have a different name (and parameter labels).  It would also allow protocol methods which have identical signatures and semantics, but different names to be implemented using the same method (i.e ‘implements D.z & E.w’).
> 
> When something is cast to the protocol (say ‘as B’), then calling the property (e.g. ‘x’) would end up calling the implementation of the renamed property ( ‘y’ in this example) on the conforming type.
> 
> I think we would also want a way to retroactively conform using existing properties/methods in an extension declaring conformance.  Not sure what the best syntax for that would be.  Off the top of my head (though I would love to have something with less cruft):
> 
> 	extension D:B {
> 		@conform(to: B.x, with: D.y)
> 	}
> 
> or maybe just:
> 	
> 	extension D:B {
> 		D.y implements B.x
> 	}
> 	
> 
> All of this is merely to start the discussion, so feel free to propose better syntax or a more elegant solution...
> 
> Thoughts?
> 
> Thanks,
> Jon
> 
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

What about if we synthesised members on the conforming type? So I’m thinking

  protocol MyProtoOne {
  	func doSomething()
  }

  protocol MyProtoTwo {
  	func doSomething()
  }

  struct ImplementsOne : MyProtoOne {
  	func doSomething() {
  		// Unambiguous. Satisfies MyProtoOne.
  	}
  }

  struct ImplementsBoth : MyProtoOne, MyProtoTwo {
  	
  	func MyProtoOne.doSomething() {
  		// Or some other declaration modifier to say this for MyProtoOne
  	}

  	func MyProtoTwo.doSomething() {
  		// ...
  	}
  }

ImplementsOne().doSomething() // unambiguous intention at call-site
ImplementsBoth().MyProtoOne.doSomething() // intention at call-site must be explicit. What kind of thing do you want to look at ImplementsBoth() as?
ImplementsBoth().MyProtoTwo.doSomething()

I think this would be relatively simple to implement. We just disambiguate at declaration site, and the synthesised members ImplementsBoth().MyProto{One/Two} are the protocol-witness tables to disambiguate at the call-site.

The thing is that we would need to mangle those names differently, and for ABI resilience (the ability to add a protocol with a conflicting name later) that would mean also mangling the protocol name in to the non-conflicting cases (ImplementsOne.MyProtoOne.doSomething). That means if you had ImplementsOne.doSomething in v1 and added the MyProtoOne protocol in v1.1, you would need to add a plain doSomething() method which doesn’t belong to a protocol.

That’s the thing — members would kind of “belong” to the protocol conformance on the type, rather than being plain top-level members on the type itself (although as long as there are no conflicts, you could use them as such and the compiler would know which members you mean). That may be beneficial for mixins.

Karl



More information about the swift-evolution mailing list