> On Aug 24, 2016, at 3:39 AM, Jonathan Hull via swift-evolution > <swift-evolution@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
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution