<div dir="ltr">I didn&#39;t send the link to evolution, so here it is:<div><a href="https://gist.github.com/Anton3/08a069a3b6f634bece7ad666922741d2">https://gist.github.com/Anton3/08a069a3b6f634bece7ad666922741d2</a></div><div><br></div><div>Response inline:</div><div class="gmail_extra"><br><div class="gmail_quote">2016-07-14 20:52 GMT+03:00 Adrian Zubarev via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span>:<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><ul>
<li><p>There is a small typo (SE–0090 is not accepted yet) - only in the first example:</p>

<pre><code>func unsafeBitCast&lt;T, U&gt;(_: T, to: U.Type)
unsafeBitCast(10, to: Double)
     
// The second line should be
unsafeBitCast(10, to: Double.self)</code></pre></li></ul></div></div></blockquote><div>I&#39;ll fix the examples.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><ul>
<li><blockquote>
<p>Size and internal structure of Type<u></u> will be the same as of T.Type <u></u></p>
</blockquote>

<ul>
<li>Do we really need this to be the same?</li></ul></li></ul></div></div></blockquote><div>Yes, otherwise we cannot remove <font face="monospace, monospace">T.Type</font>. If you want to store <i>additional</i> data in <font face="monospace, monospace">Type&lt;T&gt;</font> and have a reason for that, then why not.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><ul><li><ul>
</ul></li>
<li><blockquote>
<p>Values of Type<u></u> store identifiers of U such that U: T.<u></u></p>
</blockquote>

<ul>
<li>Why would we want to store more than one unique identifier?</li></ul></li></ul></div></div></blockquote><div>Another try at explaining my model of <font face="monospace, monospace">Type&lt;T&gt;</font>. Warning: it will be a long read this time!</div><div><br></div><div>During compilation, each type is assigned a unique integer identifier. Let&#39;s suppose there are only three types used in the program: <font face="monospace, monospace">Any</font> is 1, <font face="monospace, monospace">BaseClass</font> is 2, <font face="monospace, monospace">DerivedClass</font> is 3.</div><div><br></div><div>Values of type <font face="monospace, monospace">Type&lt;Any&gt;</font> can contain one of identifiers 1, 2 or 3.</div><div>Values of type <font face="monospace, monospace">Type&lt;BaseClass&gt;</font> can contain one of identifiers 2 or 3.</div><div>Values of type <font face="monospace, monospace">Type&lt;DerivedClass&gt;</font> can only contain 3.</div><div><br></div><div>The same in terms of sets:<br></div><div><br></div><div><font face="monospace, monospace">Type&lt;Any&gt; = { 1, 2, 3 }</font></div><div><font face="monospace, monospace">Type&lt;BaseClass&gt; = { 2, 3 }</font></div><div><font face="monospace, monospace">Type&lt;DerivedClass&gt; = { 3 }</font></div><div><br></div><div>In terms of set theory, type <font face="monospace, monospace">Type&lt;T&gt;</font> contains identifiers of all types <font face="monospace, monospace">U</font> that are subtypes of <font face="monospace, monospace">T</font>.</div><div>If <font face="monospace, monospace">U1</font>, ..., Uk are subtypes of <font face="monospace, monospace">T</font> used in the program, then <font face="monospace, monospace">Type&lt;T&gt;</font> = { T, U1, ..., Uk }</div><div><br></div><div>Example:</div><div><br></div><div><font face="monospace, monospace">let x = Type&lt;MyType&gt;()</font></div><font face="monospace, monospace">let y = Type&lt;MyProtocol&gt;(casting: x)<br>Type&lt;MyType&gt;.size      //=&gt; 50<br>Type&lt;MyProtocol&gt;.size  //=&gt; 40</font><div><font face="monospace, monospace">x.size                 //=&gt; 50</font></div><div><font face="monospace, monospace">y.size                 //=&gt; 50</font></div><div><br></div><div>Again, example with <font face="monospace, monospace">dynamicType</font>. Let&#39;s suppose that <font face="monospace, monospace">T = BaseClass</font> and <font face="monospace, monospace">DerivedClass: BaseClass</font>.</div><div><br></div><div><font face="monospace, monospace">func dynamicType(_ value: BaseClass) -&gt; Type&lt;BaseClass&gt;</font></div><div><br></div><div>We can&#39;t know statically, which type information it returns.</div><div><font face="monospace, monospace">Type&lt;BaseClass&gt; = { 2, 3 }</font></div><div>At runtime, we get to know if <font face="monospace, monospace">value</font> is of <font face="monospace, monospace">BaseClass</font> or of <font face="monospace, monospace">DerivedClass</font>.</div><div><br></div><div>In my version, <font face="monospace, monospace">Type&lt;T&gt;</font> should get all capabilities and all syntax of <font face="monospace, monospace">T.Type</font>, therefore we should be able to drop the latter.</div><div><br></div><div>Again, main idea: <b>rename</b> <font face="monospace, monospace">T.Type</font> to <font face="monospace, monospace">Type&lt;T&gt;</font><font face="arial, helvetica, sans-serif">, <b>maintain</b> its behaviour and tweak syntax</font>.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>Actually I thought for a while about the negative effect of fully removing metatypes from the language. Metatypes allow us to build neat looking execution branches like showed in SE–0101.<br>

<pre><code>extension MemoryLayout&lt;T&gt; {
    init(_ : @autoclosure () -&gt; T) {}
    public static func of(_ candidate : @autoclosure () -&gt; T) -&gt; MemoryLayout&lt;T&gt;.Type {
        return MemoryLayout.init(candidate).dynamicType
    }
}

// Value
let x: UInt8 = 5
MemoryLayout.of(x).size // 1
MemoryLayout.of(1).size // 8
MemoryLayout.of(&quot;hello&quot;).stride // 24
MemoryLayout.of(29.2).alignment // 8
</code></pre>

<p>I wouldn’t want to throw this away.</p></div></div></blockquote><div>We won&#39;t lose literally anything by moving from <font face="monospace, monospace">T.Type</font> to <font face="monospace, monospace">Type&lt;T&gt;</font>.</div><div><br></div><div><font face="monospace, monospace">of</font> returns <font face="monospace, monospace">MemoryLayout&lt;T&gt;.Type</font>, which currently doesn&#39;t have <font face="monospace, monospace">size</font> property. Could you correct your example?</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>

<p>I played with the idea of keeping <code>T.Type</code> internally but disallow it in public declarations. Furthermore metatypes would still exist, but can only be instantiated through <code>Type&lt;T&gt;.metatype</code> or <code>Type&lt;T&gt;().metatype</code>.</p>

<p>To keep the neat designing feature but get rid of <code>T.Type</code> we could abuse generic typealiases here:</p>

<pre><code>// T.Type would be only visible here but is disallowed in public declarations
// in favor of `Metatype&lt;T&gt;`
public typealias Metatype&lt;T&gt; = T.Type

public struct Type&lt;T&gt; : Hashable, CustomStringConvertible, CustomDebugStringConvertible {

    …
    public var metatype: Metatype&lt;T&gt; { return Type&lt;T&gt;.metatype }
     
    // Internally `.self` should be renamed to `.metatype` and return
    // a metatype instance  
    public static var metatype: Metatype&lt;T&gt; { return T.metatype }
    …
}
</code></pre>

<p>That way the sample from above won’t break from its designing point, but will require some refactoring:</p>

<pre><code>extension MemoryLayout&lt;T&gt; {
    init(_ : @autoclosure () -&gt; T) {}
    public static func of(_ candidate : @autoclosure () -&gt; T) -&gt; Metatype&lt;MemoryLayout&lt;T&gt;&gt; {
        return dynamicType(MemoryLayout.init(candidate)).metatype
    }
}</code></pre></div></div></blockquote><div> If you wish, <font face="monospace, monospace">Type&lt;T&gt;</font> in my version is rebranded metatype <font face="monospace, monospace">T.Type</font>.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><pre><span style="font-family:arial,sans-serif">We should also mention that dynamic casts need some tweaking to work with </span><code>Type&lt;T&gt;</code><span style="font-family:arial,sans-serif">.</span></pre></div></div></blockquote><div>In the gist, I suggest to live without tweaking and replace dynamic casts with failable initializer of <font face="monospace, monospace">Type&lt;T&gt;</font>. That will tweaking syntax of that casts, but reduce amount of magic.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><pre><span style="font-family:arial,sans-serif">And one more thing:</span><br></pre>

<pre><code>public var size: Int      { get }
public var stride: Int    { get }
public var alignment: Int { get }

public static var size: Int      { return Type&lt;T&gt;().size }
public static var stride: Int    { return Type&lt;T&gt;().stride }
public static var alignment: Int { return Type&lt;T&gt;().alignment }
</code></pre>

<p>Shouldn’t these work exactly the opposite way? If in the future <code>Type&lt;T&gt;</code> would be extended with reflection functionality and contain more stored properties, it would be lightweight to compute <code>size</code> etc. from static <code>size</code> without the need of instantiating the whole type.</p></div></div></blockquote><div>See example above with sizes.</div></div></div></div>