<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 29, 2015, at 12:06 PM, Kevin Ballard via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class="">


<title class=""></title>

<div class=""><div class="">I briefly skimmed your proposal, so I apologize if you already addressed this, but it occurs to me that we could support automatic protocol forwarding today on a per-protocol basis simply by declaring a separate protocol that provides default implementations doing the forwarding. Handling of Self return types can then be done by adding a required initializer (or just not implementing that method, so the concrete type is forced to deal with it even though everything else is forwarded).<br class=""></div>
<div class="">&nbsp;</div>
<div class="">For example, if I want to automatically forward SequenceType to a member, I can do something like<br class=""></div>
<div class="">&nbsp;</div>
<div class=""><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span> SequenceTypeForwarder : <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">SequenceType</span> {</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">typealias</span> ForwardedSequenceType : SequenceType</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span> forwardedSequence : <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">ForwardedSequenceType</span> { <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">get</span> }</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">extension</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> </span>SequenceTypeForwarder<span style="font-variant-ligatures: no-common-ligatures;" class=""> {</span></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> generate() -&gt; </span>ForwardedSequenceType<span style="font-variant-ligatures: no-common-ligatures;" class="">.</span>Generator<span style="font-variant-ligatures: no-common-ligatures;" class=""> {</span></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> forwardedSequence.generate()</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> underestimateCount() -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span> {</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> forwardedSequence.underestimateCount()</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> map&lt;T&gt;(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> transform: (ForwardedSequenceType.Generator.Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -&gt; T) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -&gt; [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">T</span>] {</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">try</span> forwardedSequence.map(transform)</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> filter(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> includeElement: (ForwardedSequenceType.Generator.Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -&gt; Bool) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -&gt; [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">ForwardedSequenceType</span>.<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Generator</span>.<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Element</span>] {</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">try</span> forwardedSequence.filter(includeElement)</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> forEach(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> body: (ForwardedSequenceType.Generator.Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -&gt; Void) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> {</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">try</span> forwardedSequence.forEach(body)</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> dropFirst(n: </span>Int<span style="font-variant-ligatures: no-common-ligatures;" class="">) -&gt; </span>ForwardedSequenceType<span style="font-variant-ligatures: no-common-ligatures;" class="">.</span>SubSequence<span style="font-variant-ligatures: no-common-ligatures;" class=""> {</span></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> forwardedSequence.dropFirst(n)</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> dropLast(n: </span>Int<span style="font-variant-ligatures: no-common-ligatures;" class="">) -&gt; </span>ForwardedSequenceType<span style="font-variant-ligatures: no-common-ligatures;" class="">.</span>SubSequence<span style="font-variant-ligatures: no-common-ligatures;" class=""> {</span></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> forwardedSequence.dropLast(n)</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> prefix(maxLength: </span>Int<span style="font-variant-ligatures: no-common-ligatures;" class="">) -&gt; </span>ForwardedSequenceType<span style="font-variant-ligatures: no-common-ligatures;" class="">.</span>SubSequence<span style="font-variant-ligatures: no-common-ligatures;" class=""> {</span></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> forwardedSequence.prefix(maxLength)</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> suffix(maxLength: </span>Int<span style="font-variant-ligatures: no-common-ligatures;" class="">) -&gt; </span>ForwardedSequenceType<span style="font-variant-ligatures: no-common-ligatures;" class="">.</span>SubSequence<span style="font-variant-ligatures: no-common-ligatures;" class=""> {</span></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> forwardedSequence.suffix(maxLength)</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> split(maxSplit: Int, allowEmptySlices: Bool, <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> isSeparator: (ForwardedSequenceType.Generator.Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -&gt; Bool) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -&gt; [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">ForwardedSequenceType</span>.<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">SubSequence</span>] {</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">try</span> forwardedSequence.split(maxSplit, allowEmptySlices: allowEmptySlices, isSeparator: isSeparator)</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div></div></div></blockquote><div><br class=""></div><div>FWIW,</div><div><br class=""></div><a href="https://github.com/apple/swift/blob/master/stdlib/public/core/SequenceWrapper.swift" class="">https://github.com/apple/swift/blob/master/stdlib/public/core/SequenceWrapper.swift</a></div><div><br class=""></div><div>Though I don’t know why we still have this; it’s not used anywhere and should probably be removed. &nbsp;I think it was supposed to be part of the new lazy sequence/collection subsystem but it was never incorporated.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div class="">
<div class="">With this protocol declared, I can then say something like<br class=""></div>
<div class="">&nbsp;</div>
<div class=""><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">struct</span> Foo {</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span> ary: [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span>]</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">extension</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> </span>Foo<span style="font-variant-ligatures: no-common-ligatures;" class=""> : </span>SequenceTypeForwarder<span style="font-variant-ligatures: no-common-ligatures;" class=""> {</span></div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span> forwardedSequence: [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span>] { <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> ary }</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div>
<div class="">&nbsp;</div>
<div class="">and my struct Foo now automatically implements SequenceType by forwarding to its variable `ary`.<br class=""></div>
<div class="">&nbsp;</div>
<div class="">The downside to this is it needs to be manually declared for each protocol. But I wager that most protocols actually aren't really amenable to forwarding anyway.<br class=""></div>
<div class="">&nbsp;</div>
<div class="">-Kevin Ballard</div>

<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=JfMPa-2F7wwZPzsZ3QKA8NjtONIYX4SjbWuUxtpfsTY2hhI3v8QnpPSi-2FxsYaa7tVKf7yF1VKLri6MOMq73YX2nNU8usSuPRjudk0FltucGJaIeshbnFbEPlImYqIP3jLlk6GyQopq6-2BndReThVjbAXSzzS8nYW8v8Uk-2FHC8Q-2Ff0meMn4gn9UkDgn5irGM37ISQIyUI1o-2F15-2BimCnJmHFpD1fKQ3NbFA3OWqUMXMO9HZ8-3D" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;" class="">
</div>


_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>