<div dir="ltr"><div class="markdown-here-wrapper" style=""><p style="margin:0px 0px 1.2em!important">2016-09-30 22:48 GMT+03:00 Xiaodi Wu via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;:</p>
<p style="margin:0px 0px 1.2em!important"></p><div class="markdown-here-exclude"><p></p><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Sorry, my question at least has nothing to do with bikeshedding. I&#39;m confused about why the proposal feels it&#39;s necessary to have both Type and Subtype. I don&#39;t understand Brent&#39;s two reasons and was hoping for some elaboration. I&#39;ve tried to clarify my question in a gist:<div><br></div><div><a href="https://gist.github.com/xwu/0cc2c8d358f1fdf066ba739bcd151167" target="_blank">https://gist.github.com/xwu/<wbr>0cc2c8d358f1fdf066ba739bcd1511<wbr>67</a></div></div></blockquote><p></p></div><p style="margin:0px 0px 1.2em!important"></p>
<p style="margin:0px 0px 1.2em!important">Regardless of syntax, there are <code style="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">Metatype&lt;T&gt;</code> and <code style="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">ExistentialMetatype&lt;T&gt;</code> “under the hood”. I’ll take the liberty to use these names for this post.</p>
<p style="margin:0px 0px 1.2em!important">Purpose and difference between the two kinds of metatypes is easy to understand. If it helps, size of <code style="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">Metatype&lt;T&gt;</code> is typically <code style="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">0</code> while size of <code style="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">ExistentialMetatype&lt;T&gt;</code> is typically <code style="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">8</code>.</p>
<p style="margin:0px 0px 1.2em!important">NOTE: <code style="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">Metatype&lt;P&gt;</code> can’t be a subtype of <code style="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">ExistentialMetatype&lt;P&gt;</code> for protocols <code style="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">P</code>, because protocols do not implement their own static requirements.</p>
<p style="margin:0px 0px 1.2em!important">Apparently, creators of Swift also thought that two kinds of metatypes are too difficult for an average developer. So an attempt was made to unify both under a single name, <code style="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">T.Type</code>. For “final” types like structs, <code style="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">T.Type</code> maps onto <code style="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">Metatype&lt;T&gt;</code>. For classes and protocols, <code style="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">T.Type</code> maps onto <code style="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">ExistentialMetatype&lt;T&gt;</code>.</p>
<p style="margin:0px 0px 1.2em!important">This abstraction turned out to be leaky. I’ll give 3 leaks.</p>
<ol style="margin:1.2em 0px;padding-left:2em">
<li style="margin:0.5em 0px">Because of Note, we could not have ID of a protocol itself inside of any kind of metatype. This feature was needed in real code. The solution was to add <code style="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">T.Protocol</code> syntax that could only be used for protocols to create a <code style="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">Metatype&lt;T&gt;</code>. But this solution created a plethora of other inconsistencies and abstraction leaks (which were explored by Adrian). Arguably the most important is (2).</li>
<li style="margin:0.5em 0px">In generic functions accepting <code style="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">T.Type</code>, passing <code style="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">T.self</code> creates an instance of <code style="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">T.Protocol</code>, which is still described in code as <code style="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">T.Type</code>. <em>boom!</em></li>
<li style="margin:0.5em 0px">Accepting static metatypes in functions is often what people want. Consider the following basic example:</li>
</ol>
<pre style="font-family:Consolas,Inconsolata,Courier,monospace;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-swift" style="font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248);display:block!important"><span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">create</span><span class="hljs-generics">&lt;T: Creatable&gt;</span><span class="hljs-params">(type: T.<span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">Type</span>)</span></span><span style="font-size:0.85em">
</span></code></pre>
<p style="margin:0px 0px 1.2em!important">Most probably, <code style="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">create</code> does not read contents of <code style="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">type</code> to deal with appropriate subtype. It does not support existentiality, <code style="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">type</code> is here for function specialization. But in case <code style="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">T</code> is subtypable, we still pass around those 8 bytes that are not used by the <code style="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">create</code>, confusing both compiler and some developers. In 90% cases, when we see such a function, it throws off value of metatype instance.</p>
<div title="MDH:PGRpdiBjbGFzcz0iZ21haWxfZXh0cmEiPjxkaXYgY2xhc3M9ImdtYWlsX3F1b3RlIj4yMDE2LTA5
LTMwIDIyOjQ4IEdNVCswMzowMCBYaWFvZGkgV3UgdmlhIHN3aWZ0LWV2b2x1dGlvbiA8c3BhbiBk
aXI9Imx0ciI+Jmx0OzxhIGhyZWY9Im1haWx0bzpzd2lmdC1ldm9sdXRpb25Ac3dpZnQub3JnIiB0
YXJnZXQ9Il9ibGFuayI+c3dpZnQtZXZvbHV0aW9uQHN3aWZ0Lm9yZzwvYT4mZ3Q7PC9zcGFuPjo8
YnI+PGJsb2NrcXVvdGUgY2xhc3M9ImdtYWlsX3F1b3RlIiBzdHlsZT0ibWFyZ2luOjAgMCAwIC44
ZXg7Ym9yZGVyLWxlZnQ6MXB4ICNjY2Mgc29saWQ7cGFkZGluZy1sZWZ0OjFleCI+PGRpdiBkaXI9
Imx0ciI+U29ycnksIG15IHF1ZXN0aW9uIGF0IGxlYXN0IGhhcyBub3RoaW5nIHRvIGRvIHdpdGgg
YmlrZXNoZWRkaW5nLiBJJ20gY29uZnVzZWQgYWJvdXQgd2h5IHRoZSBwcm9wb3NhbCBmZWVscyBp
dCdzIG5lY2Vzc2FyeSB0byBoYXZlIGJvdGggVHlwZSBhbmQgU3VidHlwZS4gSSBkb24ndCB1bmRl
cnN0YW5kIEJyZW50J3MgdHdvIHJlYXNvbnMgYW5kIHdhcyBob3BpbmcgZm9yIHNvbWUgZWxhYm9y
YXRpb24uIEkndmUgdHJpZWQgdG8gY2xhcmlmeSBteSBxdWVzdGlvbiBpbiBhIGdpc3Q6PGRpdj48
YnI+PC9kaXY+PGRpdj48YSBocmVmPSJodHRwczovL2dpc3QuZ2l0aHViLmNvbS94d3UvMGNjMmM4
ZDM1OGYxZmRmMDY2YmE3MzliY2QxNTExNjciIHRhcmdldD0iX2JsYW5rIiBkYXRhLXNhZmVyZWRp
cmVjdHVybD0iaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS91cmw/aGw9cnUmYW1wO3E9aHR0cHM6Ly9n
aXN0LmdpdGh1Yi5jb20veHd1LzBjYzJjOGQzNThmMWZkZjA2NmJhNzM5YmNkMTUxMTY3JmFtcDtz
b3VyY2U9Z21haWwmYW1wO3VzdD0xNDc1MzUyNTY5ODI4MDAwJmFtcDt1c2c9QUZRakNORjB1ZU1t
X2lMN1NMVkpiZ3lEZFNpSWVRazg0QSI+aHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20veHd1Lzx3YnI+
MGNjMmM4ZDM1OGYxZmRmMDY2YmE3MzliY2QxNTExPHdicj42NzwvYT48L2Rpdj48L2Rpdj48L2Js
b2NrcXVvdGU+PGRpdj48YnI+PC9kaXY+PGRpdj5DdXJyZW50bHksIHJlZ2FyZGxlc3Mgb2YgZXh0
ZXJuYWwgc3ludGF4LCB0aGVyZSBhcmUgYE1ldGF0eXBlJmx0O1QmZ3Q7YCBhbmQgYEV4aXN0ZW50
aWFsTWV0YXR5cGUmbHQ7VCZndDtgICJ1bmRlciB0aGUgaG9vZCIuIEknbGwgdGFrZSB0aGUgbGli
ZXJ0eSB0byB1c2UgdGhlc2UgbmFtZXMgZm9yIHRoaXMgcG9zdC48L2Rpdj48ZGl2Pjxicj48L2Rp
dj48ZGl2PlB1cnBvc2UgYW5kIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIGtpbmRzIG9mIG1l
dGF0eXBlcyBpcyBlYXN5IHRvIHVuZGVyc3RhbmQuIElmIGl0IGhlbHBzLCBzaXplIG9mIGBNZXRh
dHlwZSZsdDtUJmd0O2AgaXMgdHlwaWNhbGx5IGAwYCB3aGlsZSBzaXplIG9mIGBFeGlzdGVudGlh
bE1ldGF0eXBlJmx0O1QmZ3Q7YCBpcyB0eXBpY2FsbHkgYDhgLjwvZGl2PjxkaXY+PGJyPjwvZGl2
PjxkaXY+Tk9URTogYE1ldGF0eXBlJmx0O1AmZ3Q7YCBjYW4ndCBiZSBhIHN1YnR5cGUgb2YgYEV4
aXN0ZW50aWFsTWV0YXR5cGUmbHQ7UCZndDtgIGZvciBwcm90b2NvbHMgYFBgLCBiZWNhdXNlIHBy
b3RvY29scyBkbyBub3QgaW1wbGVtZW50IHRoZWlyIG93biBzdGF0aWMgcmVxdWlyZW1lbnRzLjwv
ZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+QXBwYXJlbnRseSwgY3JlYXRvcnMgb2YgU3dpZnQgYWxz
byB0aG91Z2h0IHRoYXQgdHdvIGtpbmRzIG9mIG1ldGF0eXBlcyBhcmUgdG9vIGRpZmZpY3VsdCBm
b3IgYW4gYXZlcmFnZSBkZXZlbG9wZXIuIFNvIGFuIGF0dGVtcHQgd2FzIG1hZGUgdG8gdW5pZnkg
Ym90aCB1bmRlciBhIHNpbmdsZSBuYW1lLCBgVC5UeXBlYC4gRm9yICJmaW5hbCIgdHlwZXMgbGlr
ZSBzdHJ1Y3RzLCBgVC5UeXBlYCBtYXBzIG9udG8gYE1ldGF0eXBlJmx0O1QmZ3Q7YC4gRm9yIGNs
YXNzZXMgYW5kIHByb3RvY29scywgYFQuVHlwZWAgbWFwcyBvbnRvIGBFeGlzdGVudGlhbE1ldGF0
eXBlJmx0O1QmZ3Q7YC48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PlRoaXMgYWJzdHJhY3Rpb24g
dHVybmVkIG91dCB0byBiZSBsZWFreS4gSSdsbCBnaXZlIDMgbGVha3MuPC9kaXY+PGRpdj48YnI+
PC9kaXY+PGRpdj4xLiBCZWNhdXNlIG9mIE5vdGUsIHdlIGNvdWxkIG5vdCBoYXZlIElEIG9mIGEg
cHJvdG9jb2wgaXRzZWxmIGluc2lkZSBvZiBhbnkga2luZCBvZiBtZXRhdHlwZS4gQW5kIHRoaXMg
ZmVhdHVyZSB3YXMgbmVlZGVkIGluIHJlYWwgY29kZS4gVGhlIHNvbHV0aW9uIHdhcyB0byBhZGQg
YFQuUHJvdG9jb2xgIHN5bnRheCB0aGF0IGNvdWxkIGJlIHVzZWQgb25seSBmb3IgcHJvdG9jb2xz
IHRvIGNyZWF0ZSBhIGBNZXRhdHlwZSZsdDtUJmd0O2AuIEJ1dCB0aGlzIHNvbHV0aW9uIGNyZWF0
ZWQgYSBwbGV0aG9yYSBvZiBvdGhlciBpbmNvbnNpc3RlbmNpZXMgYW5kIGFic3RyYWN0aW9uIGxl
YWtzICh3aGljaCB3ZXJlIGV4cGxvcmVkIGJ5IEFkcmlhbiksIGFuZCBhcmd1YWJseSB0aGUgbW9z
dCBpbXBvcnRhbnQgaXMgKDIpLjwvZGl2PjxkaXY+Mi4gSW4gZ2VuZXJpYyBmdW5jdGlvbnMgYWNj
ZXB0aW5nIGBULlR5cGVgLCBwYXNzaW5nIGBULnNlbGZgIGNyZWF0ZXMgYW4gaW5zdGFuY2Ugb2Yg
YFQuUHJvdG9jb2xgLCB3aGljaCBpcyBzdGlsbCBkZXNjcmliZWQgaW4gY29kZSBhcyBgVC5UeXBl
YC4gKmJvb20qPC9kaXY+PGRpdj4zLiBBY2NlcHRpbmcgc3RhdGljIG1ldGF0eXBlcyBpbiBmdW5j
dGlvbnMgaXMgb2Z0ZW4gd2hhdCBwZW9wbGUgd2FudC4gQ29uc2lkZXIgdGhlIGZvbGxvd2luZyBi
YXNpYyBleGFtcGxlOjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+YGBgc3dpZnQ8L2Rpdj48ZGl2
PmZ1bmMgY3JlYXRlJmx0O1Q6IENyZWF0YWJsZSZndDsodHlwZTogVC5UeXBlKTwvZGl2PjxkaXY+
YGBgPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5Nb3N0IHByb2JhYmx5LCBgY3JlYXRlYCBkb2Vz
IG5vdCByZWFkIGNvbnRlbnRzIG9mIGB0eXBlYCB0byBkZWFsIHdpdGggYXBwcm9wcmlhdGUgc3Vi
dHlwZS4gSXQgZG9lcyBub3Qgc3VwcG9ydCBleGlzdGVudGlhbGl0eSwgYHR5cGVgIGlzIGhlcmUg
Zm9yIGZ1bmN0aW9uIHNwZWNpYWxpemF0aW9uLiBCdXQgaW4gY2FzZSBgVGAgaXMgc3VidHlwYWJs
ZSwgd2Ugc3RpbGwgcGFzcyBhcm91bmQgdGhvc2UgOCBieXRlcyB0aGF0IGFyZSBub3QgdXNlZCBi
eSB0aGUgYGNyZWF0ZWAsIGNvbmZ1c2luZyBib3RoIGNvbXBpbGVyIGFuZCBzb21lIGRldmVsb3Bl
cnMuIEluIDkwJSBjYXNlcywgd2hlbiB3ZSBzZWUgc3VjaCBhIGZ1bmN0aW9uLCBpdCB0aHJvd3Mg
b2ZmIHZhbHVlIG9mIG1ldGF0eXBlIGluc3RhbmNlLjwvZGl2PjwvZGl2PjwvZGl2Pg==" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0">​</div></div></div>