<div dir="ltr">I still didn't answer the original question:<div><div><br></div><div>>> Values of Type store identifiers of U such that U: T.</div><div>>Why would we want to store more than one unique identifier?<br></div></div><div><br></div><div>We don't. What I meant is the following.</div><div><font face="monospace, monospace">Type<T></font> can have multiple non-equal values. Each of them contains a single identifier of some type <font face="monospace, monospace">U:T</font>. This type <font face="monospace, monospace">U</font> is different for non-equal values of <font face="monospace, monospace">Type<T></font>.</div></div><div class="gmail_extra"><br><div class="gmail_quote">2016-07-14 22:01 GMT+03:00 Anton Zhilin <span dir="ltr"><<a href="mailto:antonyzhilin@gmail.com" target="_blank">antonyzhilin@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I didn't send the link to evolution, so here it is:<div><a href="https://gist.github.com/Anton3/08a069a3b6f634bece7ad666922741d2" target="_blank">https://gist.github.com/Anton3/08a069a3b6f634bece7ad666922741d2</a></div><div><br></div><div>Response inline:</div><div class="gmail_extra"><br><div class="gmail_quote"><span class="">2016-07-14 20:52 GMT+03:00 Adrian Zubarev via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></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<T, U>(_: 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></span><div>I'll fix the examples.</div><span class=""><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></span><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<T></font> and have a reason for that, then why not.</div><span class=""><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></span><div>Another try at explaining my model of <font face="monospace, monospace">Type<T></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<Any></font> can contain one of identifiers 1, 2 or 3.</div><div>Values of type <font face="monospace, monospace">Type<BaseClass></font> can contain one of identifiers 2 or 3.</div><div>Values of type <font face="monospace, monospace">Type<DerivedClass></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<Any> = { 1, 2, 3 }</font></div><div><font face="monospace, monospace">Type<BaseClass> = { 2, 3 }</font></div><div><font face="monospace, monospace">Type<DerivedClass> = { 3 }</font></div><div><br></div><div>In terms of set theory, type <font face="monospace, monospace">Type<T></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<T></font> = { T, U1, ..., Uk }</div><div><br></div><div>Example:</div><div><br></div><div><font face="monospace, monospace">let x = Type<MyType>()</font></div><font face="monospace, monospace">let y = Type<MyProtocol>(casting: x)<br>Type<MyType>.size //=> 50<br>Type<MyProtocol>.size //=> 40</font><div><font face="monospace, monospace">x.size //=> 50</font></div><div><font face="monospace, monospace">y.size //=> 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) -> Type<BaseClass></font></div><div><br></div><div>We can't know statically, which type information it returns.</div><div><font face="monospace, monospace">Type<BaseClass> = { 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<T></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<T></font><font face="arial, helvetica, sans-serif">, <b>maintain</b> its behaviour and tweak syntax</font>.</div><span class=""><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<T> {
init(_ : @autoclosure () -> T) {}
public static func of(_ candidate : @autoclosure () -> T) -> MemoryLayout<T>.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></span><div>We won't lose literally anything by moving from <font face="monospace, monospace">T.Type</font> to <font face="monospace, monospace">Type<T></font>.</div><div><br></div><div><font face="monospace, monospace">of</font> returns <font face="monospace, monospace">MemoryLayout<T>.Type</font>, which currently doesn't have <font face="monospace, monospace">size</font> property. Could you correct your example?</div><span class=""><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<T>.metatype</code> or <code>Type<T>().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<T>`
public typealias Metatype<T> = T.Type
public struct Type<T> : Hashable, CustomStringConvertible, CustomDebugStringConvertible {
…
public var metatype: Metatype<T> { return Type<T>.metatype }
// Internally `.self` should be renamed to `.metatype` and return
// a metatype instance
public static var metatype: Metatype<T> { 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<T> {
init(_ : @autoclosure () -> T) {}
public static func of(_ candidate : @autoclosure () -> T) -> Metatype<MemoryLayout<T>> {
return dynamicType(MemoryLayout.init(candidate)).metatype
}
}</code></pre></div></div></blockquote></span><div> If you wish, <font face="monospace, monospace">Type<T></font> in my version is rebranded metatype <font face="monospace, monospace">T.Type</font>.</div><span class=""><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<T></code><span style="font-family:arial,sans-serif">.</span></pre></div></div></blockquote></span><div>In the gist, I suggest to live without tweaking and replace dynamic casts with failable initializer of <font face="monospace, monospace">Type<T></font>. That will tweaking syntax of that casts, but reduce amount of magic.</div><span class=""><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<T>().size }
public static var stride: Int { return Type<T>().stride }
public static var alignment: Int { return Type<T>().alignment }
</code></pre>
<p>Shouldn’t these work exactly the opposite way? If in the future <code>Type<T></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></span><div>See example above with sizes.</div></div></div></div>
</blockquote></div><br></div>