<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br><br>Sent from my iPad</div><div><br>On Mar 2, 2017, at 6:56 PM, Tony Allevato via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div>newtype feels like a leaky abstraction. Since the new type carries all the protocol conformance and members of the original type, in your example, I could add or divide RecordIds; but if they're database concepts, why would I want to do that?<br><br>If the original type were extended to add members or protocols, would the newtype gain those as well? It must, since types can be split into extensions like that in Swift a priori. So the new type is always effectively a subtype of the original, when what you often want is something that starts off with a smaller subset of its operations instead, and people can extend it in ways you don't expect.<br><br>I'm trying to imagine types where I automatically want *every* operation of its originating type, and having trouble. Even for a unit-like API, there are likely to be arithmetic operations that don't make sense.<br><br>I think a better model would be a general protocol forwarding mechanism for existing type constructs. Then I could define RecordId as a struct, internally it might have an underlying Int representation, but I would explicitly state which protocols I wanted the type to conform to and which of those are forwarded to that underlying Int. This allows us to maintain the semantic importance of protocols and build types in a way that fits existing Swift patterns, and without the magic/danger that newtype could provide.<br><br>The drawback is that if you want only a subset of operations in a protocol, you don't get that easily for free. But you could define your own protocol, retroactively conform the origin type to it *internally*, and then publicly conform the new type and forward... and as far as I can tell, that plugs the abstraction's leaks.<br></div></blockquote><div><br></div><div>Agree. &nbsp;I have shared a rough draft of a protocol-based forwarding proposal last year. &nbsp;I was midway through a second draft when it became clear it was out of scope. &nbsp;I'm planning to revive it when the time is right.</div><br><blockquote type="cite"><div><div class="gmail_quote"><div dir="ltr">On Thu, Mar 2, 2017 at 4:08 PM Anton Zhilin via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="m_-8390134894059640746markdown-here-wrapper gmail_msg"><p style="margin:0px 0px 1.2em!important" class="gmail_msg">2017-03-03 2:13 GMT+03:00 Slava Pestov &lt;<a href="mailto:spestov@apple.com" class="gmail_msg" target="_blank">spestov@apple.com</a>&gt;:</p>
<p style="margin:0px 0px 1.2em!important" class="gmail_msg"></p><div class="m_-8390134894059640746markdown-here-exclude gmail_msg"><p class="gmail_msg"></p><blockquote class="gmail_quote gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg">Does newtype add any new capability that’s not already covered by defining a struct?</div></div></blockquote><p class="gmail_msg"></p></div><p style="margin:0px 0px 1.2em!important" class="gmail_msg"></p>
</div></div><div dir="ltr" class="gmail_msg"><div class="m_-8390134894059640746markdown-here-wrapper gmail_msg"><p style="margin:0px 0px 1.2em!important" class="gmail_msg"><code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="gmail_msg">newtype</code> would forward all members and conformances of the underlying type:</p>
<pre style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px" class="gmail_msg"><code class="m_-8390134894059640746hljs m_-8390134894059640746language-swift gmail_msg" style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;white-space:pre-wrap;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248)">newtype <span class="m_-8390134894059640746hljs-type gmail_msg" style="color:rgb(68,85,136);font-weight:bold">RecordId</span> = <span class="m_-8390134894059640746hljs-type gmail_msg" style="color:rgb(68,85,136);font-weight:bold">Int</span>

<span class="m_-8390134894059640746hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">let</span> x: <span class="m_-8390134894059640746hljs-type gmail_msg" style="color:rgb(68,85,136);font-weight:bold">RecordId</span> = <span class="m_-8390134894059640746hljs-number gmail_msg" style="color:rgb(0,128,128)">5</span>
<span class="m_-8390134894059640746hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">let</span> y = x + <span class="m_-8390134894059640746hljs-number gmail_msg" style="color:rgb(0,128,128)">10</span>

<span class="m_-8390134894059640746hljs-class gmail_msg"><span class="m_-8390134894059640746hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">extension</span> <span class="m_-8390134894059640746hljs-title gmail_msg" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">RecordId</span> </span>{
    <span class="m_-8390134894059640746hljs-func gmail_msg"><span class="m_-8390134894059640746hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="m_-8390134894059640746hljs-title gmail_msg" style="color:rgb(153,0,0);font-weight:bold">load</span><span class="m_-8390134894059640746hljs-params gmail_msg">()</span> -&gt; <span class="m_-8390134894059640746hljs-title gmail_msg" style="color:rgb(153,0,0);font-weight:bold">String</span> </span>{ … }
}

<span class="m_-8390134894059640746hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">let</span> a = x.load()
<span class="m_-8390134894059640746hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">let</span> b = <span class="m_-8390134894059640746hljs-number gmail_msg" style="color:rgb(0,128,128)">42</span>.load()  <span class="m_-8390134894059640746hljs-comment gmail_msg" style="color:rgb(153,153,136);font-style:italic">// error</span>
</code></pre>
<p style="margin:0px 0px 1.2em!important" class="gmail_msg"><code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="gmail_msg">newtype</code>s aim to carry purely semantic information, in this case, that those integers can be used to fetch records from a database. We get additional members only when we are sure that semantic of current instance is appropriate.</p>
<p style="margin:0px 0px 1.2em!important" class="gmail_msg">As a side effect, it essentially allows to declare one-liner structs with pattern matching. But I agree with Jaden, just adding pattern matching to structs feels more practical. And this feature is more or less orthogonal to the core functionality of <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="gmail_msg">newtype</code>.</p>
<div title="MDH:PGRpdiBjbGFzcz0iZ21haWxfZXh0cmEiPjxkaXYgY2xhc3M9ImdtYWlsX3F1b3RlIj4yMDE3LTAz
LTAzIDI6MTMgR01UKzAzOjAwIFNsYXZhIFBlc3RvdiA8c3BhbiBkaXI9Imx0ciI+Jmx0OzxhIGhy
ZWY9Im1haWx0bzpzcGVzdG92QGFwcGxlLmNvbSIgdGFyZ2V0PSJfYmxhbmsiPnNwZXN0b3ZAYXBw
bGUuY29tPC9hPiZndDs8L3NwYW4+OjxibG9ja3F1b3RlIGNsYXNzPSJnbWFpbF9xdW90ZSIgc3R5
bGU9Im1hcmdpbjogMHB4IDBweCAwcHggMC44ZXg7IGJvcmRlci1sZWZ0OiAxcHggc29saWQgcmdi
KDIwNCwgMjA0LCAyMDQpOyBwYWRkaW5nLWxlZnQ6IDFleDsiPjxkaXYgc3R5bGU9IndvcmQtd3Jh
cDogYnJlYWstd29yZDsiPjxkaXY+RG9lcyBuZXd0eXBlIGFkZCBhbnkgbmV3IGNhcGFiaWxpdHkg
dGhhdOKAmXMgbm90IGFscmVhZHkgY292ZXJlZCBieSBkZWZpbmluZyBhIHN0cnVjdD88L2Rpdj48
L2Rpdj48L2Jsb2NrcXVvdGU+PGRpdj48YnI+PC9kaXY+PGRpdj5gbmV3dHlwZWAgd291bGQgZm9y
d2FyZCBhbGwgbWVtYmVycyBhbmQgY29uZm9ybWFuY2VzIG9mIHRoZSB1bmRlcmx5aW5nIHR5cGU6
PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5gYGBzd2lmdDwvZGl2PjxkaXY+bmV3dHlwZSBSZWNv
cmRJZCA9IEludDwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+bGV0IHg6IFJlY29yZElkID0gNTwv
ZGl2PjxkaXY+bGV0IHkgPSB4ICsgMTA8L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PmV4dGVuc2lv
biBSZWNvcmRJZCB7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7IGZ1bmMgbG9hZCgpIC0mZ3Q7IFN0
cmluZyB7IOKApiB9PC9kaXY+PGRpdj59PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5sZXQgYSA9
IHgubG9hZCgpPC9kaXY+PGRpdj5sZXQgYiA9IDQyLmxvYWQoKSAmbmJzcDsvLyBlcnJvcjwvZGl2
PjxkaXY+YGBgPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5gbmV3dHlwZWBzIGFpbSB0byBjYXJy
eSBwdXJlbHkgc2VtYW50aWMgaW5mb3JtYXRpb24sIGluIHRoaXMgY2FzZSwgdGhhdCB0aG9zZSBp
bnRlZ2VycyBjYW4gYmUgdXNlZCB0byBmZXRjaCByZWNvcmRzIGZyb20gYSBkYXRhYmFzZS4gV2Ug
Z2V0IGFkZGl0aW9uYWwgbWVtYmVycyBvbmx5IHdoZW4gd2UgYXJlIHN1cmUgdGhhdCBzZW1hbnRp
YyBvZiBjdXJyZW50IGluc3RhbmNlIGlzIGFwcHJvcHJpYXRlLjwvZGl2PjxkaXY+PGJyPjwvZGl2
PjxkaXY+QXMgYSBzaWRlIGVmZmVjdCwgaXQgZXNzZW50aWFsbHkgYWxsb3dzIHRvIGRlY2xhcmUg
b25lLWxpbmVyIHN0cnVjdHMgd2l0aCBwYXR0ZXJuIG1hdGNoaW5nLiBCdXQgSSBhZ3JlZSB3aXRo
IEphZGVuLCBqdXN0IGFkZGluZyBwYXR0ZXJuIG1hdGNoaW5nIHRvIHN0cnVjdHMgZmVlbHMgbW9y
ZSBwcmFjdGljYWwuIEFuZCB0aGlzIGZlYXR1cmUgaXMgbW9yZSBvciBsZXNzIG9ydGhvZ29uYWwg
dG8gdGhlIGNvcmUgZnVuY3Rpb25hbGl0eSBvZiBgbmV3dHlwZWAuPC9kaXY+PC9kaXY+PC9kaXY+" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0" class="gmail_msg">​</div></div></div>
_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div>
</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>