<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>Yes, this would help with that. <br><br>Sent from my iPad</div><div><br>On Dec 8, 2015, at 11:39 PM, Alejandro Martinez via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="content-type" content="text/html; charset=utf-8"><div>Hi,</div><div>Quick mail to check if I understood correctly ;)</div><div>Since swift introduction I've been trying to explore creating more domain specific types in order to avoid passing numbers and strings around (that can mean anything) and leverage the type checker to write safer code. (For context <a href="http://alejandromp.com/blog/2015/12/5/solving-the-strings-problem-in-swift/">http://alejandromp.com/blog/2015/12/5/solving-the-strings-problem-in-swift/</a> )</div><div>You can quickly realize that it increases the safety a lot but at cost of s bunch of boilerplate. At the end you just want that your type behaves as the other (string, int) but that the type checker treats it as different types.</div><div>Seems like this proposal and making easier creating 'newtype' will be the solution for this right?</div><div>Thanks<br><br><br><div>Sent from my iPad</div></div><div><br>On 08 Dec 2015, at 22:41, Matthew Johnson via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="content-type" content="text/html; charset=utf-8"><div>Yes, it should be pretty straightforward to handle the wrapping and unwrapping for the single member / newtype case. Thanks bringing that up. I will keep that in mind if I get around to writing this proposal before someone else does.</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">Is a forwarding mechanism like this something that might be considered in the Swift 3 timeframe?<br><br>Sent from my iPad</div><div><br>On Dec 8, 2015, at 2:52 PM, Joe Groff <<a href="mailto:jgroff@apple.com">jgroff@apple.com</a>> wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><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=""></div></blockquote>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=ugfoipfLFYQJoLOuZfhEMRzWwNIL3Gkut5GUvNxqU0dcJOFJ7EUEmAbxADPgXtusKs6Yx6-2Fg5AM96AdZ0BUfBah5InRgXUueaC7dVQNpJ8Yq8CAxDGc393FZ8DcyUKQA3s-2F1FwCjtZDmIPlvmUlAfBW8-2FMhnq-2FzXMdEdWgKIEyH9eIm3048LjH-2BBiAgrJ97bDtiY3rIIQILxsyGupH-2BFvZClXt-2B5HlrsdUDWD9sjTJc-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;">
</div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=nE9rxSXA5G4kxsTVkgv43pXkLx-2B36P-2BPNJufHeY0dgdJZ2JqcBE70Zo301BxZFHsKEmSBeRHf5rSb3FlObUlc3n1NUajg1XLIs-2FQvuAZQgIQX5fC7ZGyAUevE2gDdIkz1qBTOlAFLST-2BjbpkIoM1fPtdybUF9aPg9SIdRATG32gklsiUXwXKUDDzbIihRAkXaNmg4obfMJVUdIRSYZSWqw-3D-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;">
</div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>