<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=""><div class="">As the resident you-can-already-do-this grumpy guy, I tend to agree that most protocols aren't easily amenable to forwarding, and this solution works too.</div><div class=""><br class=""></div><div class="">In general, I think that Swift already doesn't impose too much boilerplate, and I think that most features to reduce boilerplate would be better served by having a sane macro system in Swift. (This is probably not in scope for Swift 3, though.)</div><br class=""><div class="">
<span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: 'Lucida Grande'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; ">Félix</span>
</div>
<br class=""><div><blockquote type="cite" class=""><div class="">Le 29 déc. 2015 à 15:06:48, Kevin Ballard via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> a écrit :</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=""> </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=""> </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=""> <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=""> <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="" class=""> </span>SequenceTypeForwarder<span style="" 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="" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="" class=""> generate() -> </span>ForwardedSequenceType<span style="" class="">.</span>Generator<span style="" class=""> {</span></div><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="">return</span> forwardedSequence.generate()</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;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> underestimateCount() -> <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=""> <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=""> }</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=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> map<T>(<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> -> T) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -> [<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=""> <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=""> }</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=""> <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> -> Bool) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -> [<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=""> <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=""> }</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=""> <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> -> 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=""> <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=""> }</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="" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="" class=""> dropFirst(n: </span>Int<span style="" class="">) -> </span>ForwardedSequenceType<span style="" class="">.</span>SubSequence<span style="" class=""> {</span></div><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="">return</span> forwardedSequence.dropFirst(n)</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="" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="" class=""> dropLast(n: </span>Int<span style="" class="">) -> </span>ForwardedSequenceType<span style="" class="">.</span>SubSequence<span style="" class=""> {</span></div><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="">return</span> forwardedSequence.dropLast(n)</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="" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="" class=""> prefix(maxLength: </span>Int<span style="" class="">) -> </span>ForwardedSequenceType<span style="" class="">.</span>SubSequence<span style="" class=""> {</span></div><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="">return</span> forwardedSequence.prefix(maxLength)</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="" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="" class=""> suffix(maxLength: </span>Int<span style="" class="">) -> </span>ForwardedSequenceType<span style="" class="">.</span>SubSequence<span style="" class=""> {</span></div><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="">return</span> forwardedSequence.suffix(maxLength)</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;" class=""> <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> -> Bool) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -> [<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=""> <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=""> }</div><div style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div>
<div class=""> </div>
<div class="">With this protocol declared, I can then say something like<br class=""></div>
<div class=""> </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=""> <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="" class=""> </span>Foo<span style="" class=""> : </span>SequenceTypeForwarder<span style="" class=""> {</span></div><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="">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=""> </div>
<div class="">and my struct Foo now automatically implements SequenceType by forwarding to its variable `ary`.<br class=""></div>
<div class=""> </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=""> </div>
<div class="">-Kevin Ballard</div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=iRI3beHTe3UxYAHTlV3lA38zIPfHMhyuRzgTmGKV6k7xvqm2SXpuwBaXgo1QYI67kYn35C2XVWTZPEPnp-2BaWU-2F5yf5eRiYeaq2lqPyEoBR1x-2BlFWyoG0Ia8OAAlLpvczXfAM4XNJ3BAZBms4PUBx6TvckO3oiebDe7QY3tNM4ZGRAQ9LmzmKOjNDizm4C-2FezNjJVGRrZQQo1tt0ZVyv-2F3gc8zJjEplGfadgdtMpwvd4-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>