[swift-evolution] Renaming for Protocol Conformance

Charles Srstka cocoadev at charlessoft.com
Wed Aug 24 03:56:19 CDT 2016


> On Aug 24, 2016, at 3:39 AM, Jonathan Hull via swift-evolution <swift-evolution at swift.org> wrote:
> 
> To take your example of walk().  Perhaps we have a protocol ‘Walkable’ which refers to any data structure where the nodes can be walked using the ‘walk()’ function.  It is easy to imagine two different protocols A & B which specialize on this in different ways (say LinearWalkable & RandomWalkable), and both add some methods/properties and use those to provide efficient default implementations.  At some point, you may run into a data structure which could easily be walked in both ways.
> 
> As things are right now, you couldn’t inherit from both protocols.  While you could add new ‘linearWalk()’ & ‘randomWalk()’ to the protocols respectively (cluttering their interface), there is still the issue of what to do when 'walk()’ is called.  You can’t rename walk() in the originating protocols because it comes from their common ancestor.  Much better to force one (or both) of the methods to be renamed on the conforming data structure.  That keeps the interfaces of the protocols clean and makes the options available on the data structure clearer (e.g. ‘walk()’ & ‘randomWalk()’ )
> 
> What I have had to do in the current version is inherit from the original protocol and then copy and paste the default implementations from the specialized versions.  Now my code has been duplicated and is harder to maintain.  We can do better.

I had a very similar situation, in fact. I solved it like this (using your protocol names for the purpose of making it easily contrastable):

protocol Walkable {
	func walk()
}

protocol LinearWalkable: Walkable {
	func linearWalk()	
}

extension LinearWalkable {
	func linearWalk { … }

	func walk() { self.linearWalk() }
}

protocol RandomWalkable {
	func randomWalk()
}

extension RandomWalkable {
	func randomWalk() { … }

	func walk() { self.randomWalk() }
}

struct S: LinearWalkable, RandomWalkable {
	func walk() { self.linearWalk() }
}

Thus a type that implements one or the other of the protocols gets walk() automatically doing the right thing, and a type that implements both has to explicitly choose. This way at least avoids the duplication of code; however, it is quite ugly to have to systematically duplicate essentially every method in the protocols (and there turned out to be quite a few of these).

Charles

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


More information about the swift-evolution mailing list