<html><head><style>
body {
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        padding:1em;
        margin:auto;
        background:#fefefe;
}

h1, h2, h3, h4, h5, h6 {
        font-weight: bold;
}

h1 {
        color: #000000;
        font-size: 28pt;
}

h2 {
        border-bottom: 1px solid #CCCCCC;
        color: #000000;
        font-size: 24px;
}

h3 {
        font-size: 18px;
}

h4 {
        font-size: 16px;
}

h5 {
        font-size: 14px;
}

h6 {
        color: #777777;
        background-color: inherit;
        font-size: 14px;
}

hr {
        height: 0.2em;
        border: 0;
        color: #CCCCCC;
        background-color: #CCCCCC;
    display: inherit;
}

p, blockquote, ul, ol, dl, li, table, pre {
        margin: 15px 0;
}

a, a:visited {
        color: #4183C4;
        background-color: inherit;
        text-decoration: none;
}

#message {
        border-radius: 6px;
        border: 1px solid #ccc;
        display:block;
        width:100%;
        height:60px;
        margin:6px 0px;
}

button, #ws {
        font-size: 12 pt;
        padding: 4px 6px;
        border-radius: 5px;
        border: 1px solid #bbb;
        background-color: #eee;
}

code, pre, #ws, #message {
        font-family: Monaco;
        font-size: 10pt;
        border-radius: 3px;
        background-color: #F8F8F8;
        color: inherit;
}

code {
        border: 1px solid #EAEAEA;
        margin: 0 2px;
        padding: 0 5px;
}

pre {
        border: 1px solid #CCCCCC;
        overflow: auto;
        padding: 4px 8px;
}

pre > code {
        border: 0;
        margin: 0;
        padding: 0;
}

#ws { background-color: #f8f8f8; }


.bloop_markdown table {
border-collapse: collapse;  
font-family: Helvetica, arial, freesans, clean, sans-serif;  
color: rgb(51, 51, 51);  
font-size: 15px; line-height: 25px;
padding: 0; }

.bloop_markdown table tr {
border-top: 1px solid #cccccc;
background-color: white;
margin: 0;
padding: 0; }
     
.bloop_markdown table tr:nth-child(2n) {
background-color: #f8f8f8; }

.bloop_markdown table tr th {
font-weight: bold;
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }

.bloop_markdown table tr td {
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }

.bloop_markdown table tr th :first-child, table tr td :first-child {
margin-top: 0; }

.bloop_markdown table tr th :last-child, table tr td :last-child {
margin-bottom: 0; }

.bloop_markdown blockquote{
  border-left: 4px solid #dddddd;
  padding: 0 15px;
  color: #777777; }
  blockquote > :first-child {
    margin-top: 0; }
  blockquote > :last-child {
    margin-bottom: 0; }

code, pre, #ws, #message {
    word-break: normal;
    word-wrap: normal;
}

hr {
    display: inherit;
}

.bloop_markdown :first-child {
    -webkit-margin-before: 0;
}

code, pre, #ws, #message {
    font-family: Menlo, Consolas, Liberation Mono, Courier, monospace;
}


.send { color:#77bb77; }
.server { color:#7799bb; }
.error { color:#AA0000; }</style></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="bloop_markdown"><p>Here is the formatted gist of the possible impementation: <a href="https://gist.github.com/DevAndArtist/a5744f21107812b2d4e6baee2c55e0bf">https://gist.github.com/DevAndArtist/a5744f21107812b2d4e6baee2c55e0bf</a></p>

<p></p></div><div class="bloop_original_html"><style>body{font-family:Helvetica,Arial;font-size:13px}</style><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><br></div> <br> <div id="bloop_sign_1468530517322853120" class="bloop_sign"><div style="font-family:helvetica,arial;font-size:13px">--&nbsp;<br>Adrian Zubarev<br>Sent with Airmail</div></div> <br><p class="airmail_on">Am 14. Juli 2016 um 23:02:52, Adrian Zubarev (<a href="mailto:adrian.zubarev@devandartist.com">adrian.zubarev@devandartist.com</a>) schrieb:</p> <blockquote type="cite" class="clean_bq"><span><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div></div><div>




<title></title>



<div class="bloop_markdown">
<p>I still can’t get my head around this.</p>
<p>Originally I wanted to seal <code>T.Type</code> completely but I
realized that there are to many downsides, therefore I think it’s
better to revise the way how we construct a metatype in Swift + how
to solve the ambiguity in array/dictionary shorthand syntax + open
the door for reflections + combining SE–0101 into
<code>Type&lt;T&gt;</code>.</p>
<p>I don’t think we have to make the whole model of
<code>Type&lt;T&gt;</code> that complicated that it contains
different identifier for each type. This is already solved with
metatypes.</p>
<p>The thing I believe you misinterpret with
<code>Type&lt;T&gt;</code> being the same as <code>T.Type</code> is
that if <code>Type&lt;T&gt;</code> would act like
<code>T.Type</code>:</p>
<pre><code class="swift">T.self.init == T.init
T.self.staticMember == T.staticMember
</code></pre>
<p>We won’t be able to extend <code>Type&lt;T&gt;</code> at all
because otherwise all static members of <code>Type&lt;T&gt;</code>
would be reserved and cannot be implemented in <code>T</code>,
which is clearly not how it should work.</p>
<pre><code class="swift">Type&lt;T&gt;.init != T.init
Type&lt;T&gt;.staticMember != T.staticMember   
</code></pre>
<p>Thats why I’m talking about the <code>metatype</code> property
all the time.</p>
<p>Here is full bikeshedding implementation. I’ll use
<code>T.Metatype</code> instead of <code>T.Type</code> for internal
use only + <code>T.metatype</code> instead of <code>T.self</code>
for internal use only + I’ll drop <code>.self</code> in public use
and assume we can construct <code>Type&lt;T&gt;</code> from
<code>T</code>.</p>
<pre><code class="swift">/// `T.metatype` returns an instance of `T.Metatype` == `Metatype&lt;T&gt;`
/// `T.metatype` is only used internally and not visible in public
/// `T.Metatype` is visible in public but not allowed in declarations - use `Metatype&lt;T&gt;` instead
/// `T.self` is dropped in public
/// `T` returns an instance of `Type&lt;T&gt;` if its not part of a declaration
/// To instantiate `Metatype&lt;T&gt;` use `Type&lt;T&gt;.metatype` or `Type&lt;T&gt;().metatype`

internal func _sizeof&lt;T&gt;(_ metatype: Metatype&lt;T&gt;) -&gt; Int {
    return Int(Builtin.sizeof(metatype))
}

internal func _strideof&lt;T&gt;(_ metatype: Metatype&lt;T&gt;) -&gt; Int {
    return Int(Builtin.strideof_nonzero(metatype))
}

internal func _alignof&lt;T&gt;(_ metatype: Metatype&lt;T&gt;) -&gt; Int {
    return Int(Builtin.alignof(metatype))
}

public func unsafeBitCast&lt;T, U&gt;(_: T, to: Type&lt;U&gt;) -&gt; U { ... }

public typealias Metatype&lt;T&gt; = T.Metatype

public struct Type&lt;T&gt; : Hashable, CustomStringConvertible, CustomDebugStringConvertible {
      
    // Stored as `Any` to make `init?(casting:)` work as expected.
    // There is no need to contain different identifier like a Set!
    internal let _underlyingMetatype: Any
    internal let _uniqueIdentifier: Int
      
    public init() {
          
        self._underlyingMetatype = T.metatype
          
        // Same hash calculation like in `ObjectIdentifier`
        let rawPointerMetatype = unsafeBitCast(T.metatype, to: Builtin.RawPointer.metatype)
        self._uniqueIdentifier = Int(Builtin.ptrtoint_Word(rawPointerMetatype))
    }
      
    public init(_ copy: Type&lt;T&gt;) {

        self._underlyingMetatype = copy._underlyingMetatype
        self._uniqueIdentifier = copy._uniqueIdentifier
    }

    // Creates an instance referring to type, which is referred by `otherType`, if possible
    public init?&lt;U&gt;(casting otherType: Type&lt;U&gt;) {
          
        // check if we can up- or downcast ther metatype from `otherType` to `Metatype&lt;T&gt;`
        guard (otherType._underlyingMetatype as? Metatype&lt;T&gt;) != nil else {
            return nil
        }
          
        // create a new `Type&lt;T&gt;` but copy the metatype and the identifier from `otherType`
        self._underlyingMetatype = otherType._underlyingMetatype
        self._uniqueIdentifier = otherType._uniqueIdentifier
    }

    public func `is`&lt;U&gt;(_ otherType: Type&lt;U&gt;) -&gt; Bool {
        return Type&lt;U&gt;(casting: self) != nil
    }
      
    public var metatype: Metatype&lt;T&gt; { return Type&lt;T&gt;.metatype }
    public static var metatype: Metatype&lt;T&gt; { return T.metatype }
      
    // do not construct full `Type&lt;T&gt;` - use lightweight static calculation instead
    public var size: Int { return Type&lt;T&gt;.size }
    public var stride: Int { return Type&lt;T&gt;.stride }
    public var alignment: Int { return Type&lt;T&gt;.alignment }
      
    public static var size: Int { return _sizeof(Type&lt;T&gt;.metatype) }
    public static var stride: Int { return _strideof(Type&lt;T&gt;.metatype) }
    public static var alignment: Int { return _alignof(Type&lt;T&gt;.metatype) }
      
    public var hashValue: Int { return self._uniqueIdentifier }
      
    public var description: String {
        return "Type&lt;\(self.metatype)&gt;"
    }
      
    public var debugDescription: String {
        return "&lt;" + self.description
            + " metatype: \(self.metatype)"
            + " size: \(self.size)"
            + " stride: \(self.stride)"
            + " alignment: \(self.alignment)&gt;"
    }
}

public func ==&lt;T, U&gt;(lhs: Type&lt;T&gt;, rhs: Type&lt;U&gt;) -&gt; Bool {
    return lhs.hashValue == rhs.hashValue
}

/// class A {}
/// class B: A {}
///
/// let anything: Any = B()
///
/// `Any.Type` or `Metatype&lt;Any&gt;`
/// let metatype = dynamicType(anything)
///
/// ((metatype as? Metatype&lt;B&gt;) != nil) == true
///

// This function can only extract the metatype from an instance.
// What we'll do to the metatype is up to us.
public func `dynamicType`&lt;T&gt;(_: T) -&gt; Metatype&lt;T&gt; {
    return Type&lt;T&gt;.metatype
}
</code></pre>
<p>And proof of concept:</p>
<pre><code class="swift">typealias Metatype&lt;T&gt; = T.Type

class A {}
class B: A {}
class C {}

let metatype: Any = B.self
((metatype as? Metatype&lt;A&gt;) != nil) == true
((metatype as? Metatype&lt;B&gt;) != nil) == true
((metatype as? Metatype&lt;C&gt;) != nil) == false
</code></pre></div>
<div class="bloop_original_html">

<div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;">
<br></div>
<br>
<div id="bloop_sign_1468523677711859968" class="bloop_sign">
<div style="font-family:helvetica,arial;font-size:13px">
--&nbsp;<br>
Adrian Zubarev<br>
Sent with Airmail</div>
</div>
<br>
<p class="airmail_on">Am 14. Juli 2016 um 21:01:24, Anton Zhilin
(<a href="mailto:antonyzhilin@gmail.com">antonyzhilin@gmail.com</a>)
schrieb:</p>
<blockquote type="cite" class="clean_bq">
<div>
<div>
<div dir="ltr"><span>I didn't send the link to evolution, so here
it is:</span>
<div><span><a href="https://gist.github.com/Anton3/08a069a3b6f634bece7ad666922741d2">https://gist.github.com/Anton3/08a069a3b6f634bece7ad666922741d2</a></span></div>
<div><span><br></span></div>
<div><span>Response inline:</span></div>
<div class="gmail_extra"><span><br></span>
<div class="gmail_quote"><span>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>:</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'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 will be the same as of
T.Type</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>
<blockquote>
<p>Values of Type store identifiers of U such that U: T.</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'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&nbsp;<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 &nbsp; &nbsp; &nbsp;//=&gt; 50<br>
Type&lt;MyProtocol&gt;.size &nbsp;//=&gt; 40</font>
<div><font face="monospace, monospace">x.size &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //=&gt; 50</font></div>
<div><font face="monospace, monospace">y.size &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //=&gt; 50</font></div>
<div><br></div>
<div>Again, example with <font face="monospace, monospace">dynamicType</font>. Let'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'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("hello").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'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&nbsp;<font face="monospace, monospace">MemoryLayout&lt;T&gt;.Type</font>, which
currently doesn'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>&nbsp;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>
</div>
</div>
</blockquote>
</div>
<div class="bloop_markdown"></div>


</div></div></span></blockquote></div><div class="bloop_markdown"><p></p></div></body></html>