> 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

Reply via email to