<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 8, 2015, at 10:09 AM, Matthew Johnson <<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Would it be acceptable to make forwarding of member with Self return types optional for the forwarder (i.e. If the initializer / factory function is not provided the member is not forwarded and must be implemented manually)?<br class=""></div></div></blockquote><div><br class=""></div><div>That's definitely a reasonable answer.</div><div><br class=""></div><div>In my mind, an ideal solution would make it easy to implement 'newtypes' that wrap a type while exposing selected parts of the original type's interface. For example, if you wanted to make strongly-typed units valued as Doubles that still support arithmetic:</div><div><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><div>protocol Addable { func + (_: Self, _: Self) -> Self }</div></div><div><div><br class=""></div></div><div><div>struct Weight: Addable {</div></div><div><div> var value: Double implements Addable</div></div><div><div>}</div></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class="">struct Distance: Addable {<br class=""> var value: Double implements Addable<div><div><div><div>}</div></div></div></div></blockquote><div><div><div></div></div></div><div><div><br class=""></div><div>it'd be nice if the unwrapping and wrapping defaulted to something sensible.</div><div><br class=""></div><div>-Joe</div><br class=""><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Sent from my iPad</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class="">On Dec 8, 2015, at 11:53 AM, Joe Groff via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="">It'd definitely be awesome to support forwarding protocol conformances. One thing a forwarding design needs to consider is how to handle `Self` requirements in the forwarded protocol. If the protocol requirements consume `Self` types, you need a conversion operation to go from the forwarder to the forwardee type, such as the getter for the forwardee property.<div class="">If there are any requirements that return `Self` you'd need to additionally provide an initializer or factory function capable of building a new instance of the forwarder type from the forwardee.</div><div class=""><br class=""></div><div class="">-Joe</div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 7, 2015, at 1:33 PM, David Owens II via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">Often it is the case where one might want to implement a type that provides an interface but has inner components that actually handle the implementation. In those cases, we end up with a lot of boiler-plate code that simply turns around and invokes the on the instance.</div><div class=""><br class=""></div><div class="">Let’s take the example of class clusters:</div><div class=""><br class=""></div><div class=""><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><span class="" style="font-family: Menlo;">private protocol _Cluster {</span></div><div class=""><font face="Menlo" class=""> func description() -> String<br class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">class Cluster: _Cluster {</font></div><div class=""><font face="Menlo" class=""> </font></div><div class=""><font face="Menlo" class=""> private var _instance: _Cluster</font></div><div class=""><font face="Menlo" class=""> </font></div><div class=""><font face="Menlo" class=""> init(name: String) {</font></div><div class=""><font face="Menlo" class=""> _instance = _ClusterString(name: name)</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class=""> </font></div><div class=""><font face="Menlo" class=""> init(value: Int) {</font></div><div class=""><font face="Menlo" class=""> _instance = _ClusterValue(value: value)</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class=""> </font></div><div class=""><font face="Menlo" class=""> // this is pure boiler-plate</font></div><div class=""><font face="Menlo" class=""> func description() -> String {</font></div><div class=""><font face="Menlo" class=""> return _instance.description()</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">private class _ClusterString: _Cluster {</font></div><div class=""><font face="Menlo" class=""> private var name: String</font></div><div class=""><font face="Menlo" class=""> init(name: String) { self.name = name }</font></div><div class=""><font face="Menlo" class=""> func description() -> String {</font></div><div class=""><font face="Menlo" class=""> return "_ClusterString: \(name)"</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">private class _ClusterValue: _Cluster {</font></div><div class=""><font face="Menlo" class=""> private var value: Int</font></div><div class=""><font face="Menlo" class=""> init(value: Int) { self.value = value }</font></div><div class=""><font face="Menlo" class=""> func description() -> String {</font></div><div class=""><font face="Menlo" class=""> return "_ClusterValue: \(value)"</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">let s = Cluster(name: "a string")</font></div><div class=""><font face="Menlo" class="">s.description()</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">let v = Cluster(value: 12)</font></div><div class=""><font face="Menlo" class="">v.description()</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div></blockquote></div><div class=""><br class=""></div><div class="">Now, it would be nice to not have to have to implement the boiler-plate (this example only has a single method, so the savings seem minimal).</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class=""><span class="" style="font-family: Menlo;">class Cluster: _Cluster {</span></div></div><div class=""><div class=""><font face="Menlo" class=""> </font><span class="" style="font-family: Menlo;">@forward(_Cluster, _instance)</span></div></div><div class=""><span class="" style="font-family: Menlo;"><br class=""></span></div><div class=""><div class=""><font face="Menlo" class=""> private var _instance: _Cluster</font></div></div><div class=""><div class=""><font face="Menlo" class=""> </font></div></div><div class=""><div class=""><font face="Menlo" class=""> init(name: String) {</font></div></div><div class=""><div class=""><font face="Menlo" class=""> _instance = _ClusterString(name: name)</font></div></div><div class=""><div class=""><font face="Menlo" class=""> }</font></div></div><div class=""><div class=""><font face="Menlo" class=""> </font></div></div><div class=""><div class=""><font face="Menlo" class=""> init(value: Int) {</font></div></div><div class=""><div class=""><font face="Menlo" class=""> _instance = _ClusterValue(value: value)</font></div></div><div class=""><div class=""><font face="Menlo" class=""> }</font></div></div><div class=""><div class=""><font face="Menlo" class="">}</font></div></div><div class=""><div class=""><br class=""></div></div></blockquote><div class="">The @forward(protocol, instance) attribute lets the compiler know that the _Cluster protocol should be forwarded to the _instance value. The compiler would then generate all of the implementation stubs. Refactoring is also made simple as API changes to _Cluster do not need to be manually reflected on the type.</div><div class=""><br class=""></div><div class="">Another way to solve this problem is with a sufficiently advanced macro system. But that is out-of-scope for v3. However, this seems like it could be a straight-forward enough implementation to support in the mean-time, with an easy path for removal/update if it were to be replaced by a macro system.</div><div class=""><br class=""></div><div class="">-David</div><div class=""><br class=""></div><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=RoDF4MveSEMYBIqIJA6ub1g8cOZ-2BVYvqV-2FqygPhjPn-2FK-2FVQEwcBazah4R74GOQP0PQHgtMxJKXpIwDMF-2FshTQ7xcId7zfu-2BgRiWkpIPuJdMy8WxOl9-2BcW03zSI8eF5WyY1Iw6WkEkE4CkRTpD9sJk3BiJd-2FKUoEOhs3vgYsLBlvQVzFn8Gf5Kl8K4LWhz2kxw-2FhRs0jUp5kRgn-2Bhg9kD9c-2FSriu7mHrqifAOxPrvPxQ-3D" alt="" width="1" height="1" border="0" class="" style="height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;"></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=eLFMrKDT8iBxZ-2Fbnk-2BZqvSchNN-2FvYXdceA0T7VxwkAeqDmF0KtyZcv984vBjsjqVdhkzPIkf5fEW9c2eB2OFx0x7AwlmlDFG8nV-2BXVAm-2BsbIs0IjRSKUnjDq-2FXKlTri07WmPBQg-2BjU8JbUON93-2FNEEXg5k-2BLmFRxOiCfyd-2B-2FSckQzGiuV2o7fphqa2pxC3o8-2Fozp7wrSFPM4K-2BJ9EznEyidoTPjhS5js-2BYhY4ihLOvQ-3D" alt="" width="1" height="1" border="0" style="height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;" class=""></div></blockquote><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span></div></blockquote></div></blockquote></div><br class=""></body></html>