I like that. Have you considered the following?
protocol foobar { func foo() … func bar() ... } class A: foobar { …} class B: foobar { let a = A() implements foobar.foo let b = A() implements foobar.bar } Regards, Rien Site: http://balancingrock.nl Blog: http://swiftrien.blogspot.com Github: http://github.com/Swiftrien Project: http://swiftfire.nl > On 25 Nov 2016, at 16:33, Jay Abbott via swift-evolution > <swift-evolution@swift.org> wrote: > > We already have a great way to compose APIs using protocol composition, and > we can supply default implementations for protocol methods, but what if we > want to compose implementations from existing types? > > Say I have two disparate protocols: > > protocol A > { > > func methodA1() > > > func methodA2() > > } > > protocol B > { > > func methodB1() > > > func methodB2() > > } > > And I also have a selection of classes that implement them, but let’s just > consider two: > > class ImplementsA : A > { > > func methodA1() > { > > print("A1" > ) > } > > func methodA2() > { > > print("A2" > ) > } > } > > class ImplementsB : B > { > > func methodB1() > { > > print("B1" > ) > } > > func methodB2() > { > > print("B2" > ) > } > } > > And I have a composed interface: > > typealias Useful = A & B > Now I want to implement a Useful class by composing it from the two chosen > implementations of A and B: > > class MyClass : Useful > { > private > let a = ImplementsA > () > private > let b = ImplementsB > () > > public > func methodA1() > { > a.methodA1() > } > public > func methodA2() > { > a.methodA2() > } > public > func methodB1() > { > b.methodB1() > } > public > func methodB2() > { > b.methodB2() > > // I want this to do what 'b' does, plus some > > > // extra work in MyClass implementations of B > > > print("Extra" > ) > } > } > > Not too bad - but that could get pretty tedious if I had 5 protocols to > implement with 5 methods each. Much nicer would be: > > class MyClass : Useful > { > private > let a = ImplementsA() implements A > > private > let b = ImplementsB() implements B > > > public > func methodB2() > { > b.methodB2() > > // I want this to do whatever 'b' does, plus some > > > // extra work in MyClass implementations of B > > > print("Extra" > ) > } > } > > The idea is that implements SomeProtocol after a member variable will > synthesize all the methods that aren’t explicitly implemented from > SomeProtcol by forwarding the call to that member. Or something more > efficient if possible. > > You could also implement protocols using other classes that only partially > implement them: > > class PartlyImplementsB > { > > func methodB1() > { > > print("B1" > ) > } > } > > class MyClass : Useful > { > private > let a = ImplementsA() implements A > > private > let b = PartlyImplementsB() implements B > > > public > func methodB2() > { > > print("I have to implement this because `b` does not." > ) > } > } > > The way this would work is find the intersection between all methods in the > protocol and all methods in the implementing member, then subtract all > methods already explicitly implemented in the class, and synthesize those. > That way if you had another class AlmostImplementsB that implements methodB2 > you could simply do: > > private let a = ImplementsA() implements A > > private > let b1 = PartlyImplementsB() implements B > > private > let b2 = AlmostImplementsB() implements B > However, if the synthesis process finds that it’s synthesizing a method > twice, for example in this case… > > protocol C > { > > func methodC1() > > > func methodC2() > > > func methodC3() > > } > > class PartlyImplementsC > { > > func methodC1() > { > > print("C1(partly)" > ) > } > > func methodC2() > { > > print("C2(partly)" > ) > } > } > > class AlmostImplementsC > { > > func methodC2() > { > > print("C2(almost)" > ) > } > > func methodC3() > { > > print("C3(almost)" > ) > } > } > > class MyClass : C > { > private > let cPartly = PartlyImplementsC() implements C > > private > let cAlmost = AlmostImplementsC() implements C > > } > > …then the compiler would emit an error and you would have to explicitly > implement methodC2 to prevent it from being double-synthesized. You could of > course have your own custom implementation or choose which member to call as > your explicit implementation. > > Regarding access: I think it would implement them as public, as this seems > obvious for a protocol, but I guess there’s a possibility you might want them > to be internal, so perhaps implements(internal) or implements(public) would > be better. Or perhaps someone can think of a better word because in the > partial case it is a little confusing - is there a single word that means > use-to-implement ? > > Regarding value-types: I haven’t thought deeply about this for non-class > types, but it can probably work the same for those too. > > Anyway, this could be used to provide a variety of implementations for > protocols, composed of different combinations of partial implementations, > then use those complete implementations to compose your larger/complex types > with the minimum of boilerplate forwarding code. > > Thoughts? > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution