<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 Jun 9, 2017, at 2:53 PM, Tony Allevato &lt;<a href="mailto:tony.allevato@gmail.com" class="">tony.allevato@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">+1 to this. My ideal imagining of this behavior is to:<br class=""><div class=""><br class=""></div><div class="">1) Define a protocol containing the precise operations you want to support via forwarding.</div><div class="">2) Internally/fileprivately extend the original type to conform to this protocol.</div><div class="">3) In your new type, tell it to forward protocol members for a particular property (the underlying String, or whatever) and the compiler will synthesize the protocol member stubs on the new type.</div><div class=""><br class=""></div><div class="">There are definitely finer details to be worked out but that's a rough sketch of how I've been imagining it could work. Nice advantages include (1) if there already exists a protocol that defines the exact operations you want to forward, you can skip step 2, and (2) it's explicit/opt-in synthesis where you have to provide the members to forward (this is expected, at a minimum), but you don't have to write all the boilerplate implementations.</div></div></div></blockquote><div><br class=""></div><div>I have a mostly finished second draft of a protocol-oriented forwarding proposal which is pretty similar to what you describe here. &nbsp;The most important difference is that while protocols are used to perform forwarding neither type is required to actually conform to the protocol. &nbsp;</div><div><br class=""></div><div>That turns out to be pretty important when you think about edge cases. &nbsp;Sometimes you don’t actually want the forwardee to conform (that’s probably why you said internal / fileprivate). &nbsp;Sometimes you also don’t want the forwarder to conform. &nbsp;IIRC, there are also cases where it cannot conform (I would have to dig up the proposal to recall the details).</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div></div><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Fri, Jun 9, 2017 at 12:47 PM Matthew Johnson via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 9, 2017, at 2:39 PM, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank" class="">xiaodi.wu@gmail.com</a>&gt; wrote:</div><br class="m_-5898496471598027137Apple-interchange-newline"><div class="">Interesting. So you’d want `newtype Foo = String` to start off with no members on Foo?<br class=""></div></blockquote><div class=""><br class=""></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class="">Yeah.&nbsp; Previous discussions of newtype have usually led to discussion of ways to forward using a protocol-oriented approach.&nbsp; Nothing has gotten too far, but it usually comes up that suppressing undesired members is important.</div><div class=""><br class=""></div><div class="">It is also important to have some way to distinguish between members with a parameter of the underlying type from members that should be treated by newtype as Self parameters.&nbsp; The mechanism we have for doing that in Swift happens to be a protocol.</div></div></div><div style="word-wrap:break-word" class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="gmail_quote"><div dir="ltr" class="">On Fri, Jun 9, 2017 at 15:18 Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" target="_blank" class="">matthew@anandabits.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 9, 2017, at 12:09 PM, Xiaodi Wu via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-5898496471598027137m_8204961224395548143Apple-interchange-newline"><div class=""><div class="">On Fri, Jun 9, 2017 at 12:44 Robert Bennett via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class=""><div class=""></div><div class="">Somewhat related to this, shouldn’t it be possible to sub-struct a struct as long as you only add functions and computed properties (i.e., no stored properties)? Traditionally structs cannot be subtyped because their size must be known at compile time. I don’t know the implementation details of where functions and computed properties live, but something tells me they belong to the type and not the object (although I’ve never really made the effort to sit down and fully understand Swift’s type model), in which case adding them to a struct’s definition would not change the size of the object on the stack. Thus it should be possible to make custom substructs of String that add additional functionality but no new stored properties. Thoughts?</div></div></blockquote><div class=""><br class=""></div><div class="">Value subtyping is a large subject and, IIUC, newtype would be a subset of that topic. Unlikely to be in scope for Swift 5, though, but that’s up to the core team.</div></div></div></div></blockquote><div class=""><br class=""></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class="">I see newtype as being more related to forwarding than subtyping.&nbsp; Usually you want to hide significant parts of the interface to the wrapped type.</div></div></div><div style="word-wrap:break-word" class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class=""><div class="gmail_quote"><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class=""><div class="">On Jun 9, 2017, at 12:12 PM, Jacob Williams via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 9, 2017, at 9:53 AM, Charlie Monroe &lt;<a href="mailto:charlie@charliemonroe.net" target="_blank" class="">charlie@charliemonroe.net</a>&gt; wrote:</div><br class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-interchange-newline"><div class=""><div style="word-wrap:break-word" class="">-1 - this would disallow e.g. to share UI code between iOS and macOS:<div class=""><br class=""></div><div class="">#if os(iOS)</div><div class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">        </span>typealias XUView = UIView</div><div class="">#else</div><div class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">        </span>typealias XUView = NSView</div><div class="">#endif</div><div class=""><br class=""></div><div class="">extension XUView {</div><div class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">        </span>...</div><div class="">}</div></div></div></blockquote><br class=""><div class="">I really don’t see how this disallows code sharing between the two systems? Could you explain further? Based on my understanding of the pitch, this is valid code still. (Although I do like the suggestion of a new keyword rather than just limiting type alias).</div><div class=""><br class=""></div><div class="">Even if your example was invalid, you could also just do something like this:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">#if os(iOS)</font></div><div class=""><font face="Menlo" class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">        </span>typealias XUView = UIView</font></div><div class=""><font face="Menlo" class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">        </span>extension XUView {</font></div><div class=""><font face="Menlo" class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">                </span>//extension code here</font></div><div class=""><font face="Menlo" class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">        </span>}</font></div><div class=""><font face="Menlo" class="">#if os(macOS)</font></div><div class=""><font face="Menlo" class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">        </span>typealias XUView = UIView</font></div><div class=""><font face="Menlo" class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">        </span>extension XUView {</font></div><div class=""><font face="Menlo" class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">                </span>// extension code here</font></div><div class=""><font face="Menlo" class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">        </span>}</font></div><div class=""><font face="Menlo" class="">#endif</font><br class=""><div class=""><br class=""></div><div class="">While not as pretty, still just as effective if you have to deal with different types based on the system being compiled for and you could easily still make the type alias extensions for each type work the same.</div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 9, 2017, at 9:53 AM, Charlie Monroe &lt;<a href="mailto:charlie@charliemonroe.net" target="_blank" class="">charlie@charliemonroe.net</a>&gt; wrote:</div><br class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-interchange-newline"><div class=""><div style="word-wrap:break-word" class="">-1 - this would disallow e.g. to share UI code between iOS and macOS:<div class=""><br class=""></div><div class="">#if os(iOS)</div><div class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">        </span>typealias XUView = UIView</div><div class="">#else</div><div class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">        </span>typealias XUView = NSView</div><div class="">#endif</div><div class=""><br class=""></div><div class="">extension XUView {</div><div class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">        </span>...</div><div class="">}</div><div class=""><br class=""></div><div class="">or with any similar compatibility typealiases.</div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 9, 2017, at 5:38 PM, Jacob Williams via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-interchange-newline"><div class=""><div style="word-wrap:break-word" class="">+1 from me.<div class=""><br class=""></div><div class="">There have been times I’ve wanted to subclass an object (such as String) but since it is a non-class, non-protocol type you can only extend Strings existing functionality which adds that same functionality to Strings everywhere. It would be nice if we could either extend type aliases (and only the type alias), or if it were possible to inherit from structs so that we could create a custom string type like so:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">struct HeaderKey: String {</font></div><div class=""><font face="Menlo" class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">        </span>static var lastModified: String { return “Last-Modified” }</font></div><div class=""><font face="Menlo" class=""><span class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-tab-span" style="white-space:pre-wrap">        </span>static var host: String { return “Host” }</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><br class=""></div><div class="">I realize that struct inheritance is far less likely, since that defeats one of the main pieces of what makes a struct a struct. So I’m all for this proposal of allowing type aliases to be extended as though they were their own struct/class.</div><div class=""><br class=""></div><div class="">Unfortunately, I’m not sure how feasible this kind of functionality would actually be, but if it’s possible then I’m in favor of implementing it.</div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 8, 2017, at 10:14 PM, Yvo van Beek via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-5898496471598027137m_8204961224395548143m_8809170826063233257Apple-interchange-newline"><div class=""><div class="">Typealiases can greatly reduce the complexity of code. But I think one change in how the compiler handles them could make them even more powerful.<div class=""><br class=""></div><div class="">Let's say I'm creating a web server framework and I've created a simple dictionary to store HTTP headers (I know that headers are more complex than that, but as an example). I could write something like this:</div><div class=""><br class=""></div><div class=""><div class="">&nbsp; &nbsp; <font face="monospace, monospace" color="#0b5394" class="">typealias HeaderKey = String</font></div><div class=""><font face="monospace, monospace" color="#0b5394" class=""><br class=""></font></div><div class=""><font face="monospace, monospace" color="#0b5394" class="">&nbsp; var headers = [HeaderKey: String]()</font></div><div class=""><font face="monospace, monospace" color="#0b5394" class="">&nbsp; headers["Host"] = "<a href="http://domain.com/" target="_blank" class="">domain.com</a>"</font></div></div><div class=""><br class=""></div><div class="">Now I can define a couple of default headers like this:</div><div class=""><br class=""></div><div class=""><div class=""><font color="#0b5394" face="monospace, monospace" class="">&nbsp;&nbsp;extension HeaderKey {</font></div><div class=""><font color="#0b5394" face="monospace, monospace" class="">&nbsp;&nbsp;&nbsp;&nbsp;static var lastModified: String { return "Last-Modified" }</font></div><div class=""><font color="#0b5394" face="monospace, monospace" class="">&nbsp;&nbsp;&nbsp;&nbsp;static var host: String { return "Host" }</font></div><div class=""><font color="#0b5394" face="monospace, monospace" class="">&nbsp;&nbsp;}</font></div></div><div class=""><br class=""></div><div class="">After that I can do this:<br class=""></div><div class=""><br class=""></div><div class=""><div class=""><span style="color:rgb(11,83,148);font-family:monospace,monospace" class="">&nbsp;&nbsp;</span><font color="#0b5394" class=""><font face="monospace, monospace" class="">var headers = [HeaderKey: String]()</font></font></div><div class=""><span style="color:rgb(11,83,148);font-family:monospace,monospace" class="">&nbsp;&nbsp;</span><font face="monospace, monospace" color="#0b5394" class="">headers[.host] = "<a href="http://domain.com/" target="_blank" class="">domain.com</a>"</font></div><div class=""><span style="color:rgb(11,83,148);font-family:monospace,monospace" class="">&nbsp;&nbsp;</span><font face="monospace, monospace" color="#0b5394" class="">headers[.lastModified] = "some date"</font><font face="monospace, monospace" color="#0b5394" class=""><br class=""></font></div><div class=""><span style="color:rgb(11,83,148);font-family:monospace,monospace" class="">&nbsp;&nbsp;</span><font face="monospace, monospace" color="#0b5394" class="">headers["X-MyHeader"] = "This still works too"</font></div></div><div class=""><font face="monospace, monospace" color="#0b5394" class=""><br class=""></font></div><div class="">But unfortunately the extension is also applied to normal strings:<font face="monospace, monospace" color="#0b5394" class=""><br class=""></font></div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; <font color="#0b5394" face="monospace, monospace" class="">var normalString: String = .host</font><br class=""></div><div class=""><font color="#0b5394" face="monospace, monospace" class=""><br class=""></font></div><div class="">Perhaps it would be better if the extension would only apply to the parts of my code where I use the HeaderKey typealias and not to all Strings. This could be a great tool to specialize classes by creating a typealias and adding functionality to it. Another example I can think of is typealiases for dictionaries or arrays with added business logic through extensions (especially since you can't inherit from structs).<font color="#0b5394" face="monospace, monospace" class=""><br class=""></font></div><div class=""><br class=""></div><div class="">If you want to create an extension that adds functionality to all Strings you could have created an extension for String instead of HeaderKey.</div><div class=""><br class=""></div><div class="">Please let me know what you think. I'm not sure how complex this change would be.</div><div class="">I could write a proposal if you're interested.</div><div class=""><br class=""></div><div class="">Kind regards,</div><div class="">Yvo</div></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></div></div></div></blockquote><blockquote type="cite" 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" target="_blank" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div>_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
</blockquote></div></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div></div></blockquote></div>
</div></blockquote></div></div>_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
</blockquote></div>
</div></blockquote></div><br class=""></body></html>