<div dir="ltr"><div class="markdown-here-wrapper" style=""><p style="margin:0px 0px 1.2em!important">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?</p>
<p style="margin:0px 0px 1.2em!important">Say I have two disparate protocols:</p>
<pre style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-swift" style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248) none repeat scroll 0% 0%"><span class="hljs-class"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">protocol</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">A</span> </span>{
<span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodA1</span><span class="hljs-params">()</span>
<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodA2</span><span class="hljs-params">()</span>
}
<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">protocol</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">B</span> </span>{
<span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodB1</span><span class="hljs-params">()</span>
<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodB2</span><span class="hljs-params">()</span>
}</span>
</code></pre>
<p style="margin:0px 0px 1.2em!important">And I also have a selection of classes that implement them, but let’s just consider two:</p>
<pre style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-swift" style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248) none repeat scroll 0% 0%"><span class="hljs-class"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">class</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">ImplementsA</span> : <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">A</span> </span>{
<span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodA1</span><span class="hljs-params">()</span> </span>{
<span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">"A1"</span>)
}
<span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodA2</span><span class="hljs-params">()</span> </span>{
<span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">"A2"</span>)
}
}
<span class="hljs-class"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">class</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">ImplementsB</span> : <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">B</span> </span>{
<span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodB1</span><span class="hljs-params">()</span> </span>{
<span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">"B1"</span>)
}
<span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodB2</span><span class="hljs-params">()</span> </span>{
<span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">"B2"</span>)
}
}
</code></pre>
<p style="margin:0px 0px 1.2em!important">And I have a composed interface:</p>
<pre style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-swift" style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248) none repeat scroll 0% 0%"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">typealias</span> <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">Useful</span> = <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">A</span> & <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">B</span>
</code></pre>
<p style="margin:0px 0px 1.2em!important">Now I want to implement a <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">Useful</code> class by composing it from the two chosen implementations of <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">A</code> and <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">B</code>:</p>
<pre style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-swift" style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248) none repeat scroll 0% 0%"><span class="hljs-class"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">class</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">MyClass</span> : <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">Useful</span> </span>{
private <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> a = <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">ImplementsA</span>()
private <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> b = <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">ImplementsB</span>()
public <span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodA1</span><span class="hljs-params">()</span> </span>{
a.methodA1()
}
public <span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodA2</span><span class="hljs-params">()</span> </span>{
a.methodA2()
}
public <span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodB1</span><span class="hljs-params">()</span> </span>{
b.methodB1()
}
public <span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodB2</span><span class="hljs-params">()</span> </span>{
b.methodB2()
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic">// I want this to do what 'b' does, plus some</span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic">// extra work in MyClass implementations of B</span>
<span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">"Extra"</span>)
}
}
</code></pre>
<p style="margin:0px 0px 1.2em!important">Not too bad - but that could get pretty tedious if I had 5 protocols to implement with 5 methods each. Much nicer would be:</p>
<pre style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-swift" style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248) none repeat scroll 0% 0%"><span class="hljs-class"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">class</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">MyClass</span> : <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">Useful</span> </span>{
private <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> a = <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">ImplementsA</span>() implements <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">A</span>
private <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> b = <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">ImplementsB</span>() implements <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">B</span>
public <span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodB2</span><span class="hljs-params">()</span> </span>{
b.methodB2()
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic">// I want this to do whatever 'b' does, plus some</span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic">// extra work in MyClass implementations of B</span>
<span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">"Extra"</span>)
}
}
</code></pre>
<p style="margin:0px 0px 1.2em!important">The idea is that <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">implements SomeProtocol</code> after a member variable will synthesize all the methods that aren’t explicitly implemented from <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">SomeProtcol</code> by forwarding the call to that member. Or something more efficient if possible.</p>
<p style="margin:0px 0px 1.2em!important">You could also implement protocols using other classes that only partially implement them:</p>
<pre style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-swift" style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248) none repeat scroll 0% 0%"><span class="hljs-class"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">class</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">PartlyImplementsB</span> </span>{
<span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodB1</span><span class="hljs-params">()</span> </span>{
<span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">"B1"</span>)
}
}
<span class="hljs-class"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">class</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">MyClass</span> : <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">Useful</span> </span>{
private <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> a = <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">ImplementsA</span>() implements <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">A</span>
private <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> b = <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">PartlyImplementsB</span>() implements <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">B</span>
public <span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodB2</span><span class="hljs-params">()</span> </span>{
<span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">"I have to implement this because `b` does not."</span>)
}
}
</code></pre>
<p style="margin:0px 0px 1.2em!important">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 <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">AlmostImplementsB</code> that implements <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">methodB2</code> you could simply do:</p>
<pre style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-swift" style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248) none repeat scroll 0% 0%"> private <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> a = <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">ImplementsA</span>() implements <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">A</span>
private <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> b1 = <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">PartlyImplementsB</span>() implements <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">B</span>
private <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> b2 = <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">AlmostImplementsB</span>() implements <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">B</span>
</code></pre>
<p style="margin:0px 0px 1.2em!important">However, if the synthesis process finds that it’s synthesizing a method twice, for example in this case…</p>
<pre style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-swift" style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248) none repeat scroll 0% 0%"><span class="hljs-class"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">protocol</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">C</span> </span>{
<span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodC1</span><span class="hljs-params">()</span>
<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodC2</span><span class="hljs-params">()</span>
<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodC3</span><span class="hljs-params">()</span>
}
<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">class</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">PartlyImplementsC</span> </span>{
<span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodC1</span><span class="hljs-params">()</span> </span>{
<span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">"C1(partly)"</span>)
}
<span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodC2</span><span class="hljs-params">()</span> </span>{
<span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">"C2(partly)"</span>)
}
}
<span class="hljs-class"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">class</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">AlmostImplementsC</span> </span>{
<span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodC2</span><span class="hljs-params">()</span> </span>{
<span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">"C2(almost)"</span>)
}
<span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">methodC3</span><span class="hljs-params">()</span> </span>{
<span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">"C3(almost)"</span>)
}
}
<span class="hljs-class"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">class</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">MyClass</span> : <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">C</span> </span>{
private <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> cPartly = <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">PartlyImplementsC</span>() implements <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">C</span>
private <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> cAlmost = <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">AlmostImplementsC</span>() implements <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">C</span>
}
</code></pre>
<p style="margin:0px 0px 1.2em!important">…then the compiler would emit an error and you would have to explicitly implement <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">methodC2</code> 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.</p>
<p style="margin:0px 0px 1.2em!important">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 <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">implements(internal)</code> or <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">implements(public)</code> 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 <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">use-to-implement</code> ?</p>
<p style="margin:0px 0px 1.2em!important">Regarding value-types: I haven’t thought deeply about this for non-class types, but it can probably work the same for those too.</p>
<p style="margin:0px 0px 1.2em!important">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.</p><p style="margin:0px 0px 1.2em!important">Thoughts?</p>
<div title="MDH:PGRpdj48ZGl2PjxkaXY+PGRpdj48cCBzdHlsZT0ibWFyZ2luOiAwcHggMHB4IDEuMmVtOyI+V2Ug
YWxyZWFkeSBoYXZlIGEgZ3JlYXQgCndheSB0byBjb21wb3NlIEFQSXMgdXNpbmcgcHJvdG9jb2wg
Y29tcG9zaXRpb24sIGFuZCB3ZSBjYW4gc3VwcGx5IApkZWZhdWx0IGltcGxlbWVudGF0aW9ucyBm
b3IgcHJvdG9jb2wgbWV0aG9kcywgYnV0IHdoYXQgaWYgd2Ugd2FudCB0byAKY29tcG9zZSBpbXBs
ZW1lbnRhdGlvbnMgZnJvbSBleGlzdGluZyB0eXBlcz88L3A+CjxwIHN0eWxlPSJtYXJnaW46IDBw
eCAwcHggMS4yZW07Ij48L3A+PC9kaXY+U2F5IEkgaGF2ZSB0d28gZGlzcGFyYXRlIHByb3RvY29s
czo8YnI+PC9kaXY+YGBgc3dpZnQ8YnI+cHJvdG9jb2wgQSB7PGJyPiZuYnNwOyZuYnNwOyZuYnNw
OyBmdW5jIG1ldGhvZEExKCk8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IGZ1bmMgbWV0aG9kQTIoKTxi
cj59PGJyPnByb3RvY29sIEIgezxicj4mbmJzcDsmbmJzcDsmbmJzcDsgZnVuYyBtZXRob2RCMSgp
PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyBmdW5jIG1ldGhvZEIyKCk8YnI+fTxicj5gYGA8YnI+PGJy
PjwvZGl2PkFuZCBJIGFsc28gaGF2ZSBhIHNlbGVjdGlvbiBvZiBjbGFzc2VzIHRoYXQgaW1wbGVt
ZW50IHRoZW0sIGJ1dCBsZXQncyBqdXN0IGNvbnNpZGVyIHR3bzo8YnI+PC9kaXY+YGBgc3dpZnQ8
YnI+Y2xhc3MgSW1wbGVtZW50c0EgOiBBIHs8YnI+wqDCoMKgIGZ1bmMgbWV0aG9kQTEoKSB7PGJy
PsKgwqDCoCDCoMKgwqAgcHJpbnQoIkExIik8YnI+wqDCoMKgIH08YnI+wqDCoMKgIGZ1bmMgbWV0
aG9kQTIoKSB7PGJyPsKgwqDCoCDCoMKgwqAgcHJpbnQoIkEyIik8YnI+wqDCoMKgIH08YnI+fTxi
cj5jbGFzcyBJbXBsZW1lbnRzQiA6IEIgezxicj7CoMKgwqAgZnVuYyBtZXRob2RCMSgpIHs8YnI+
wqDCoMKgIMKgwqDCoCBwcmludCgiQjEiKTxicj7CoMKgwqAgfTxicj7CoMKgwqAgZnVuYyBtZXRo
b2RCMigpIHs8YnI+wqDCoMKgIMKgwqDCoCBwcmludCgiQjIiKTxicj7CoMKgwqAgfTxicj59PGJy
PmBgYDxicj48YnI+PGRpdj5BbmQgSSBoYXZlIGEgY29tcG9zZWQgaW50ZXJmYWNlOjxicj48L2Rp
dj48ZGl2PmBgYHN3aWZ0PGJyPnR5cGVhbGlhcyBVc2VmdWwgPSBBICZhbXA7IEI8YnI+YGBgPGJy
PjwvZGl2PjxkaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5Ob3cgSSB3YW50IHRvIGltcGxlbWVudCBh
IGBVc2VmdWxgIGNsYXNzIGJ5IGNvbXBvc2luZyBpdCBmcm9tIHRoZSB0d28gY2hvc2VuIGltcGxl
bWVudGF0aW9ucyBvZiBgQWAgYW5kIGBCYDo8YnI+PC9kaXY+PGRpdj5gYGBzd2lmdDxicj5jbGFz
cyBNeUNsYXNzIDogVXNlZnVsIHs8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IHByaXZhdGUgbGV0IGEg
PSBJbXBsZW1lbnRzQSgpPGJyPiZuYnNwOyZuYnNwOyZuYnNwOyBwcml2YXRlIGxldCBiID0gSW1w
bGVtZW50c0IoKTxicj48YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IHB1YmxpYyBmdW5jIG1ldGhvZEEx
KCkgezxicj4mbmJzcDsmbmJzcDsmbmJzcDsgJm5ic3A7Jm5ic3A7Jm5ic3A7IGEubWV0aG9kQTEo
KTxicj4mbmJzcDsmbmJzcDsmbmJzcDsgfTxicj4mbmJzcDsmbmJzcDsmbmJzcDsgcHVibGljIGZ1
bmMgbWV0aG9kQTIoKSB7PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyAmbmJzcDsmbmJzcDsmbmJzcDsg
YS5tZXRob2RBMigpPGJyPiZuYnNwOyZuYnNwOyZuYnNwOyB9PGJyPiZuYnNwOyZuYnNwOyZuYnNw
OyBwdWJsaWMgZnVuYyBtZXRob2RCMSgpIHs8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7ICZuYnNwOyZu
YnNwOyZuYnNwOyBiLm1ldGhvZEIxKCk8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IH08YnI+Jm5ic3A7
Jm5ic3A7Jm5ic3A7IHB1YmxpYyBmdW5jIG1ldGhvZEIyKCkgezxicj4mbmJzcDsmbmJzcDsmbmJz
cDsgJm5ic3A7Jm5ic3A7Jm5ic3A7IGIubWV0aG9kQjIoKTxicj4mbmJzcDsmbmJzcDsmbmJzcDsg
Jm5ic3A7Jm5ic3A7Jm5ic3A7IC8vIEkgd2FudCB0aGlzIHRvIGRvIHdoYXQgJ2InIGRvZXMsIHBs
dXMgc29tZTxicj4mbmJzcDsmbmJzcDsmbmJzcDsgJm5ic3A7Jm5ic3A7Jm5ic3A7IC8vIGV4dHJh
IHdvcmsgaW4gTXlDbGFzcyBpbXBsZW1lbnRhdGlvbnMgb2YgQjxicj4mbmJzcDsmbmJzcDsmbmJz
cDsgJm5ic3A7Jm5ic3A7Jm5ic3A7IHByaW50KCJFeHRyYSIpPGJyPiZuYnNwOyZuYnNwOyZuYnNw
OyB9PGJyPn08YnI+YGBgPGJyPjwvZGl2Pjxicj48ZGl2Pk5vdCB0b28gYmFkIC0gYnV0IHRoYXQg
Y291bGQgZ2V0IHByZXR0eSB0ZWRpb3VzIGlmIEkgaGFkIDUgcHJvdG9jb2xzIHRvIGltcGxlbWVu
dCB3aXRoIDUgbWV0aG9kcyBlYWNoLiBNdWNoIG5pY2VyIHdvdWxkIGJlOjxicj48L2Rpdj48ZGl2
PjwvZGl2PjxkaXY+YGBgc3dpZnQ8YnI+PC9kaXY+PGRpdj5jbGFzcyBNeUNsYXNzIDogVXNlZnVs
IHs8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IHByaXZhdGUgbGV0IGEgPSBJbXBsZW1lbnRzQSgpIGlt
cGxlbWVudHMgQTxicj4mbmJzcDsmbmJzcDsmbmJzcDsgcHJpdmF0ZSBsZXQgYiA9IEltcGxlbWVu
dHNCKCkgaW1wbGVtZW50cyBCPGJyPjxicj48L2Rpdj48ZGl2PiZuYnNwOyZuYnNwOyZuYnNwOyBw
dWJsaWMgZnVuYyBtZXRob2RCMigpIHs8YnI+PC9kaXY+Jm5ic3A7Jm5ic3A7Jm5ic3A7ICZuYnNw
OyZuYnNwOyZuYnNwOyBiLm1ldGhvZEIyKCk8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7ICZuYnNwOyZu
YnNwOyAmbmJzcDsvLyBJIHdhbnQgdGhpcyB0byBkbyB3aGF0ZXZlciAnYicgZG9lcywgcGx1cyBz
b21lPGJyPiZuYnNwOyZuYnNwOyZuYnNwOyAmbmJzcDsmbmJzcDsgJm5ic3A7Ly8gZXh0cmEgd29y
ayBpbiBNeUNsYXNzIGltcGxlbWVudGF0aW9ucyBvZiBCPGJyPiZuYnNwOyZuYnNwOyZuYnNwOyAm
bmJzcDsmbmJzcDsgJm5ic3A7cHJpbnQoIkV4dHJhIik8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IH08
YnI+fTxicj5gYGA8YnI+PGRpdj48YnI+PC9kaXY+PGRpdj5UaGUgaWRlYSBpcyB0aGF0IGBpbXBs
ZW1lbnRzIFNvbWVQcm90b2NvbGAgYWZ0ZXIgYSBtZW1iZXIgdmFyaWFibGUgd2lsbCBzeW50aGVz
aXplIGFsbCB0aGUgbWV0aG9kcyB0aGF0IGFyZW4ndCBleHBsaWNpdGx5IGltcGxlbWVudGVkIGZy
b20gYFNvbWVQcm90Y29sYCBieSBmb3J3YXJkaW5nIHRoZSBjYWxsIHRvIHRoYXQgbWVtYmVyLiBP
ciBzb21ldGhpbmcgbW9yZSBlZmZpY2llbnQgaWYgcG9zc2libGUuPGJyPjxicj48L2Rpdj48ZGl2
PllvdSBjb3VsZCBhbHNvIGltcGxlbWVudCBwcm90b2NvbHMgdXNpbmcgb3RoZXIgY2xhc3NlcyB0
aGF0IG9ubHkgcGFydGlhbGx5IGltcGxlbWVudCB0aGVtOjxicj48L2Rpdj48ZGl2PmBgYHN3aWZ0
PGJyPmNsYXNzIFBhcnRseUltcGxlbWVudHNCIHs8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IGZ1bmMg
bWV0aG9kQjEoKSB7PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyAmbmJzcDsmbmJzcDsmbmJzcDsgcHJp
bnQoIkIxIik8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IH08YnI+fTxicj48ZGl2PmNsYXNzIE15Q2xh
c3MgOiBVc2VmdWwgezxicj4mbmJzcDsmbmJzcDsmbmJzcDsgcHJpdmF0ZSBsZXQgYSA9IEltcGxl
bWVudHNBKCkgaW1wbGVtZW50cyBBPGJyPiZuYnNwOyZuYnNwOyZuYnNwOyBwcml2YXRlIGxldCBi
ID0gUGFydGx5SW1wbGVtZW50c0IoKSBpbXBsZW1lbnRzIEI8YnI+PGJyPjwvZGl2PjxkaXY+Jm5i
c3A7Jm5ic3A7Jm5ic3A7IHB1YmxpYyBmdW5jIG1ldGhvZEIyKCkgezxicj48L2Rpdj4mbmJzcDsm
bmJzcDsmbmJzcDsgJm5ic3A7Jm5ic3A7Jm5ic3A7IHByaW50KCJJIGhhdmUgdG8gaW1wbGVtZW50
IHRoaXMgYmVjYXVzZSBgYmAgZG9lcyBub3QuIik8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IH08YnI+
fTxicj5gYGA8YnI+PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5UaGUgd2F5IHRoaXMgd291bGQg
d29yayBpcyBmaW5kIHRoZSBpbnRlcnNlY3Rpb24gYmV0d2VlbiBhbGwgbWV0aG9kcyBpbiB0aGUg
cHJvdG9jb2wgYW5kIGFsbCBtZXRob2RzIGluIHRoZSBpbXBsZW1lbnRpbmcgbWVtYmVyLCB0aGVu
IHN1YnRyYWN0IGFsbCBtZXRob2RzIGFscmVhZHkgZXhwbGljaXRseSBpbXBsZW1lbnRlZCBpbiB0
aGUgY2xhc3MsIGFuZCBzeW50aGVzaXplIHRob3NlLiBUaGF0IHdheSBpZiB5b3UgaGFkIGFub3Ro
ZXIgY2xhc3MgYEFsbW9zdEltcGxlbWVudHNCYCB0aGF0IGltcGxlbWVudHMgYG1ldGhvZEIyYCB5
b3UgY291bGQgc2ltcGx5IGRvOjxicj48L2Rpdj48ZGl2PmBgYHN3aWZ0PGJyPjwvZGl2PjxkaXY+
Jm5ic3A7Jm5ic3A7Jm5ic3A7IHByaXZhdGUgbGV0IGEgPSBJbXBsZW1lbnRzQSgpIGltcGxlbWVu
dHMgQTxicj4mbmJzcDsmbmJzcDsmbmJzcDsgcHJpdmF0ZSBsZXQgYjEgPSBQYXJ0bHlJbXBsZW1l
bnRzQigpIGltcGxlbWVudHMgQjxicj4mbmJzcDsmbmJzcDsmbmJzcDsgcHJpdmF0ZSBsZXQgYjIg
PSBBbG1vc3RJbXBsZW1lbnRzQigpIGltcGxlbWVudHMgQjxicj5gYGA8YnI+PGJyPjwvZGl2Pjxk
aXY+SG93ZXZlciwgaWYgdGhlIHN5bnRoZXNpcyBwcm9jZXNzIGZpbmRzIHRoYXQgaXQncyBzeW50
aGVzaXppbmcgYSBtZXRob2QgdHdpY2UsIGZvciBleGFtcGxlIGluIHRoaXMgY2FzZS4uLjxicj48
L2Rpdj48ZGl2PmBgYHN3aWZ0PGJyPnByb3RvY29sIEMgezxicj4mbmJzcDsmbmJzcDsmbmJzcDsg
ZnVuYyBtZXRob2RDMSgpPGJyPiZuYnNwOyZuYnNwOyZuYnNwOyBmdW5jIG1ldGhvZEMyKCk8YnI+
Jm5ic3A7Jm5ic3A7Jm5ic3A7IGZ1bmMgbWV0aG9kQzMoKTxicj59PGJyPmNsYXNzIFBhcnRseUlt
cGxlbWVudHNDIHs8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IGZ1bmMgbWV0aG9kQzEoKSB7PGJyPiZu
YnNwOyZuYnNwOyZuYnNwOyAmbmJzcDsmbmJzcDsmbmJzcDsgcHJpbnQoIkMxKHBhcnRseSkiKTxi
cj4mbmJzcDsmbmJzcDsmbmJzcDsgfTxicj4mbmJzcDsmbmJzcDsmbmJzcDsgZnVuYyBtZXRob2RD
MigpIHs8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7ICZuYnNwOyZuYnNwOyZuYnNwOyBwcmludCgiQzIo
cGFydGx5KSIpPGJyPiZuYnNwOyZuYnNwOyZuYnNwOyB9PGJyPn08YnI+Y2xhc3MgQWxtb3N0SW1w
bGVtZW50c0Mgezxicj4mbmJzcDsmbmJzcDsmbmJzcDsgZnVuYyBtZXRob2RDMigpIHs8YnI+Jm5i
c3A7Jm5ic3A7Jm5ic3A7ICZuYnNwOyZuYnNwOyZuYnNwOyBwcmludCgiQzIoYWxtb3N0KSIpPGJy
PiZuYnNwOyZuYnNwOyZuYnNwOyB9PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyBmdW5jIG1ldGhvZEMz
KCkgezxicj4mbmJzcDsmbmJzcDsmbmJzcDsgJm5ic3A7Jm5ic3A7Jm5ic3A7IHByaW50KCJDMyhh
bG1vc3QpIik8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IH08YnI+fTxicj48L2Rpdj48ZGl2PmNsYXNz
IE15Q2xhc3MgOiBDIHs8YnI+PC9kaXY+PGRpdj4mbmJzcDsmbmJzcDsmbmJzcDsgcHJpdmF0ZSBs
ZXQgY1BhcnRseSA9IFBhcnRseUltcGxlbWVudHNDKCkgaW1wbGVtZW50cyBDPGJyPjwvZGl2Pjxk
aXY+Jm5ic3A7Jm5ic3A7Jm5ic3A7IHByaXZhdGUgbGV0IGNBbG1vc3QgPSBBbG1vc3RJbXBsZW1l
bnRzQygpIGltcGxlbWVudHMgQzxicj48L2Rpdj48ZGl2Pn08YnI+PC9kaXY+PGRpdj5gYGA8YnI+
PC9kaXY+PGRpdj4uLi50aGVuIHRoZSBjb21waWxlciB3b3VsZCBlbWl0IGFuIGVycm9yIGFuZCB5
b3Ugd291bGQgaGF2ZSB0byBleHBsaWNpdGx5IGltcGxlbWVudCBgbWV0aG9kQzJgIHRvIHByZXZl
bnQgaXQgZnJvbSBiZWluZyBkb3VibGUtc3ludGhlc2l6ZWQuIFlvdSBjb3VsZCBvZiBjb3Vyc2Ug
aGF2ZSB5b3VyIG93biBjdXN0b20gaW1wbGVtZW50YXRpb24gb3IgY2hvb3NlIHdoaWNoIG1lbWJl
ciB0byBjYWxsIGFzIHlvdXIgZXhwbGljaXQgaW1wbGVtZW50YXRpb24uPGJyPjwvZGl2PjxkaXY+
PGJyPjwvZGl2PjxkaXY+UmVnYXJkaW5nIGFjY2VzczogSSB0aGluayBpdCB3b3VsZCBpbXBsZW1l
bnQgdGhlbSBhcyBwdWJsaWMsIGFzIHRoaXMgc2VlbXMgb2J2aW91cyBmb3IgYSBwcm90b2NvbCwg
YnV0IEkgZ3Vlc3MgdGhlcmUncyBhIHBvc3NpYmlsaXR5IHlvdSBtaWdodCB3YW50IHRoZW0gdG8g
YmUgaW50ZXJuYWwsIHNvIHBlcmhhcHMgYGltcGxlbWVudHMoaW50ZXJuYWwpYCBvciBgaW1wbGVt
ZW50cyhwdWJsaWMpYCB3b3VsZCBiZSBiZXR0ZXIuIE9yIHBlcmhhcHMgc29tZW9uZSBjYW4gdGhp
bmsgb2YgYSBiZXR0ZXIgd29yZCBiZWNhdXNlIGluIHRoZSBwYXJ0aWFsIGNhc2UgaXQgaXMgYSBs
aXR0bGUgY29uZnVzaW5nIC0gaXMgdGhlcmUgYSBzaW5nbGUgd29yZCB0aGF0IG1lYW5zIGB1c2Ut
dG8taW1wbGVtZW50YCA/PGJyPjwvZGl2PjxkaXY+PGJyPjwvZGl2PlJlZ2FyZGluZyB2YWx1ZS10
eXBlczogSSBoYXZlbid0IHRob3VnaHQgZGVlcGx5IGFib3V0IHRoaXMgZm9yIG5vbi1jbGFzcyB0
eXBlcywgYnV0IGl0IGNhbiBwcm9iYWJseSB3b3JrIHRoZSBzYW1lIGZvciB0aG9zZSB0b28uPGJy
PjxkaXY+PGJyPjxkaXY+QW55d2F5LCB0aGlzIGNvdWxkIGJlIHVzZWQgdG8gcHJvdmlkZSBhIHZh
cmlldHkgb2YgaW1wbGVtZW50YXRpb25zIApmb3IgcHJvdG9jb2xzLCBjb21wb3NlZCBvZiBkaWZm
ZXJlbnQgY29tYmluYXRpb25zIG9mIHBhcnRpYWwgCmltcGxlbWVudGF0aW9ucywgdGhlbiB1c2Ug
dGhvc2UgY29tcGxldGUgaW1wbGVtZW50YXRpb25zIHRvIGNvbXBvc2UgeW91cgogbGFyZ2VyL2Nv
bXBsZXggdHlwZXMgd2l0aCB0aGUgbWluaW11bSBvZiBib2lsZXJwbGF0ZSBmb3J3YXJkaW5nIGNv
ZGUuPGJyPjwvZGl2PjxkaXY+PC9kaXY+PGJyPjwvZGl2PjxkaXY+VGhvdWdodHM/PGJyPjwvZGl2
PjwvZGl2Pg==" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0"></div></div></div>