<div dir="ltr">I posted this in your original thread; I am strongly against the notion that slightly prettier code is worth making the type system unsound, nor is it worth the performance hit from the necessary runtime checks (even if some fraction of them can be optimized out by the compiler).<div><br></div><div>In terms of getting rid of associated types, I think that any such proposal should also include a description of how SequenceType is to be rewritten using the new system, both in terms of implementation as well as usage in APIs.<br><div><br></div><div>Austin</div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jan 12, 2016 at 5:31 PM, Howard Lovatt <span dir="ltr">&lt;<a href="mailto:howard.lovatt@gmail.com" target="_blank">howard.lovatt@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">@Jordan &amp; Austin,<div><br></div><div>You raise two issues covariance and overhead of generic protocols instead of associated types in protocols.</div><div><br></div><div>Having used opt in covariance in other languages, Java &amp; Scala, I am not a fan. You end up littering all your code with a covariance annotation. Just look at any Java or Scala code, look at their libraries. Also when Sun ran there project coin, vaguely similar to swift-evolution, there was a ton of correspondence saying that people wanted covariance by default. The official answer from Oracle was that they wished they had made covariance the default but it was now too late to change; therefore there is strong presidency for covariance by default.</div><div><br></div><div>There is some overhead with the approach I suggested, however I think that the compiler can eliminate it. I will use the measure `sizeofValue` as a proxy for any type of overhead (space or time). I chose this because it is easy and because it is likely to be true that if `sizeofValue` return the same size then the overhead is likely the same. Consider a `Boxable` protocol and then an `Int` specialisation of that protocol.<div><br></div><div>User writes:</div><div><br></div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(187,44,162)">protocol</span><span style="color:rgb(0,0,0)"> Boxable&lt;T&gt; {</span><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        <span style="color:rgb(187,44,162)">var</span> value: <span style="color:rgb(112,61,170)">Any</span> { <span style="color:rgb(187,44,162)">get</span> <span style="color:rgb(187,44,162)">set</span> }<br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    }</p><div><br></div><div>This gets translated, as per proposal, into:</div><div><br></div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">    // Size test for a generic protocol and generic struct as per proposal and optimisation</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(187,44,162)">protocol</span><span style="color:rgb(0,0,0)"> Boxable { </span>// User would write `protocol Boxable&lt;T&gt; { var value: T { get set } }`.</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        <span style="color:rgb(187,44,162)">var</span> T: <span style="color:rgb(112,61,170)">Any</span>.Type { <span style="color:rgb(187,44,162)">get</span> }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        <span style="color:rgb(187,44,162)">var</span> value: <span style="color:rgb(112,61,170)">Any</span> { <span style="color:rgb(187,44,162)">get</span> <span style="color:rgb(187,44,162)">set</span> }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p><div>Then the user wants an `Int` specialisation:</div><div><br></div>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(187,44,162)">struct</span><span style="color:rgb(0,0,0)"> BoxInt: </span><span style="color:rgb(79,129,135)">Boxable</span><span style="color:rgb(0,0,0)">&lt;T&gt; {</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        <span style="color:rgb(187,44,162)">var</span> value: <span style="color:rgb(112,61,170)">Int</span><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"><br></span></p><div>This gets translated, as per proposal, into:</div><div><br></div><div></div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(187,44,162)">struct</span><span style="color:rgb(0,0,0)"> BoxInt: </span><span style="color:rgb(79,129,135)">Boxable</span><span style="color:rgb(0,0,0)"> { </span>// User would write `struct BoxInt: Boxable&lt;Int&gt; { var value: Int }`.</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)">        </span>// No need for a stored property becuse `Int` is a struct and cannot be sub-classed.<br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)">        </span><span style="color:rgb(187,44,162)">var</span><span style="color:rgb(0,0,0)"> T: </span><span style="color:rgb(112,61,170)">Any</span><span style="color:rgb(0,0,0)">.Type { </span>// Compiler generated, user would not write anything</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">            <span style="color:rgb(187,44,162)">return</span> <span style="color:rgb(112,61,170)">Int</span>.<span style="color:rgb(187,44,162)">self</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">        </p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)">        </span><span style="color:rgb(187,44,162)">var</span><span style="color:rgb(0,0,0)"> _value: </span><span style="color:rgb(112,61,170)">Any</span><span style="color:rgb(0,0,0)"> </span>// From user written `var value: Int`.</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        <span style="color:rgb(187,44,162)">var</span> value: <span style="color:rgb(112,61,170)">Any</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">            <span style="color:rgb(187,44,162)">get</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">                <span style="color:rgb(187,44,162)">return</span> <span style="color:rgb(79,129,135)">_value</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">            }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">            <span style="color:rgb(187,44,162)">set</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">                <span style="color:rgb(61,29,129)">precondition</span>(newValue <span style="color:rgb(187,44,162)">is</span> <span style="color:rgb(112,61,170)">Int</span>, <span style="color:rgb(209,47,27)">&quot;Type of newValue, </span>\<span style="color:rgb(209,47,27)">(</span>newValue.<span style="color:rgb(187,44,162)">dynamicType</span><span style="color:rgb(209,47,27)">), is not </span>\<span style="color:rgb(209,47,27)">(</span><span style="color:rgb(112,61,170)">Int</span>.<span style="color:rgb(187,44,162)">self</span><span style="color:rgb(209,47,27)">)&quot;</span>)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">                <span style="color:rgb(79,129,135)">_value</span> = newValue</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">            }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">        </p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)">        </span>// No need for `lowestCommonDeclaredT` arg becuse `Int` is a struct and cannot be sub-classed.</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)">        </span><span style="color:rgb(187,44,162)">init</span><span style="color:rgb(0,0,0)">(value: </span><span style="color:rgb(112,61,170)">Any</span><span style="color:rgb(0,0,0)">) { </span>// Compiler generated, user would not write anything</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">            <span style="color:rgb(79,129,135)">_value</span> = value</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p><div>There is some overhead:</div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p><div style="font-family:arial,sans-serif"></div><p></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    <span style="color:rgb(187,44,162)">let</span> bI = <span style="color:rgb(79,129,135)">BoxInt</span>(value: <span style="color:rgb(39,42,216)">1</span>)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(61,29,129)">sizeofValue</span><span style="color:rgb(0,0,0)">(</span><span style="color:rgb(79,129,135)">bI</span><span style="color:rgb(0,0,0)">) </span>// 32, i.e. `BoxInt (due to `value: Any`) has overhead since an `Int` size is 8</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    <span style="color:rgb(187,44,162)">let</span> boxable: <span style="color:rgb(79,129,135)">Boxable</span> = <span style="color:rgb(79,129,135)">bI</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(61,29,129)">sizeofValue</span><span style="color:rgb(0,0,0)">(</span><span style="color:rgb(79,129,135)">boxable</span><span style="color:rgb(0,0,0)">) </span>// 40, i.e. generic protocol has same overhead as non-generic protocol</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p><div>Encouragingly, once you type as a protocol, whether the protocol is a proposed generic protocol or a non-generic protocol the overhead in the same. However `BoxInt` is certainly more overhead than `Int`.</div><div><br></div><div>Fortunately the compiler can optimise it away:</div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p><div style="font-family:arial,sans-serif"></div><p></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(187,44,162)">struct</span><span style="color:rgb(0,0,0)"> NonGenericBoxInt { </span>// Also generated from `struct BoxInt: Boxable&lt;Int&gt; { var value: Int }`</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        <span style="color:rgb(187,44,162)">var</span> value: <span style="color:rgb(112,61,170)">Int</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        <span style="color:rgb(187,44,162)">var</span> toBoxInt: <span style="color:rgb(79,129,135)">BoxInt</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">            <span style="color:rgb(187,44,162)">return</span> <span style="color:rgb(79,129,135)">BoxInt</span>(value: <span style="color:rgb(79,129,135)">value</span>)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    <span style="color:rgb(187,44,162)">let</span> nGBI = <span style="color:rgb(79,129,135)">NonGenericBoxInt</span>(value: <span style="color:rgb(39,42,216)">1</span>)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(61,29,129)">sizeofValue</span><span style="color:rgb(0,0,0)">(</span><span style="color:rgb(79,129,135)">nGBI</span><span style="color:rgb(0,0,0)">) </span>// 8, i.e. `NonGenericBoxInt has zero overhead</p></div><div><br></div></div><div class="gmail_extra">When the user writes `BoxInt` the compiler substitutes `NonGenericBoxInt` and when the user covariantly assigns to the protocol `Boxable` the compiler calls `toBoxInt`.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Therefore the original proposal could be extended to include this optimisation.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Hopefully therefore this `efficiency` question is addressed?</div><div class="gmail_extra"><br></div><div class="gmail_extra">Thanks for the feedback,</div><div class="gmail_extra"><br></div><div class="gmail_extra">  -- Howard.</div><div class="gmail_extra"><div><div class="h5"><br><div class="gmail_quote">On 13 January 2016 at 05:19, Jordan Rose <span dir="ltr">&lt;<a href="mailto:jordan_rose@apple.com" target="_blank">jordan_rose@apple.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div>Agreed on both counts. Generics are more familiar but don&#39;t actually cover the use cases where the associated type is <i>not</i> independent of the model object (like a Sequence&#39;s Generator or a Collection&#39;s Index). Dropping that information results in a lot of extra indirection at runtime, which we don&#39;t want.</div><span><font color="#888888"><div><br></div><div>Jordan</div></font></span><div><div><div><br></div><div><br><div><blockquote type="cite"><div>On Jan 12, 2016, at 8:17, Austin Zheng via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br><div><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">Strong -1, covariance on generics should be explicitly opt-in. Also -1 on generics replacing associated types in protocols.</span><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Austin</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br><div><blockquote type="cite"><div>On Jan 12, 2016, at 1:45 AM, Howard Lovatt via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br><div><div style="word-wrap:break-word"><div style="margin:0px;line-height:normal"><font face="Menlo"><span style="font-size:11px">Currently you generics are invariant whereas function arguments etc. are covariant. I am suggesting that if the way generics are implemented is changed then they can be made covariant and that this will add considerable utility to Swift generics.</span></font></div><div style="margin:0px;line-height:normal"><font face="Menlo"><span style="font-size:11px"><br></span></font></div><div style="margin:0px;line-height:normal"><font face="Menlo"><span style="font-size:11px">1st a demonstration of the current situation of invariant generics:</span></font></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span><br></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>    </span>// Current system</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">   <span> </span><span style="color:rgb(187,44,162)">class</span><span> </span>Top {}</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">   <span> </span><span style="color:rgb(187,44,162)">class</span><span> </span>Bottom:<span> </span><span style="color:rgb(79,129,135)">Top</span><span> </span>{}</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">   <span> </span><span style="color:rgb(187,44,162)">struct</span><span> </span>Box&lt;T: AnyObject&gt; {</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">       <span> </span><span style="color:rgb(187,44,162)">var</span><span> </span>value:<span> </span><span style="color:rgb(112,61,170)">T</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">       <span> </span><span style="color:rgb(187,44,162)">init</span>(<span style="color:rgb(187,44,162)">_</span><span> </span>initialValue:<span> </span><span style="color:rgb(112,61,170)">T</span>) {</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">           <span> </span><span style="color:rgb(79,129,135)">value</span><span> </span>= initialValue;</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">   <span> </span><span style="color:rgb(187,44,162)">let</span><span> </span>boxB =<span> </span><span style="color:rgb(79,129,135)">Box</span>(<span style="color:rgb(79,129,135)">Bottom</span>())</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span>// let boxT: Box&lt;Top&gt; = boxB // Covariance currently not allowed</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">The key point is although `Bottom` &#39;is a’ `Top`, `Box&lt;Bottom&gt;` *is not* a `Box&lt;Top&gt;`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">I am suggesting:</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">1. That `Box&lt;Bottom&gt;` should be a `Box&lt;Top&gt;` (covariance).</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">2. An implementation that allows the above covariance.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">3. That protocols are made generic, i.e. `protocol Box&lt;T&gt; { var value: T { get set } }` and that this mechanism replaces associated types for protocols.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span>// Proposal:</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span>// 1. No change to Box, i.e. programmer would just write Box as before</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span>// 2. Code transformed by comiler with write check for each specific, generic type instance</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span>// Best approximation of resulting code in current Swift to demonstrate spirit of idea:</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span>// Compiler writes a universal form using the upper bound (it writes the underlyting representation).</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span>// In practice this would be called `Box` but used `BoxAnyObject` to indicate that it has a generic argument bounded by `AnyObject`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">   <span> </span><span style="color:rgb(187,44,162)">struct</span><span> </span>BoxAnyObject {</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>       <span> </span></span>// Generated from generic argument `&lt;T: AnyObject&gt;`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>       <span> </span></span><span style="color:rgb(187,44,162)">let</span><span><span> </span>T:<span> </span></span><span style="color:rgb(112,61,170)">AnyObject</span><span>.Type<span> </span></span>// Store the actual type.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">        <br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>       <span> </span></span>// Generated from stored property `var value: T` and noting that `T`&#39;s upper bound is `AnyObject`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>       <span> </span></span><span style="color:rgb(187,44,162)">private</span><span><span> </span></span><span style="color:rgb(187,44,162)">var</span><span><span> </span>_value:<span> </span></span><span style="color:rgb(112,61,170)">AnyObject</span><span><span> </span></span>// Access the stored property through a setter so that type can be checked</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">       <span> </span><span style="color:rgb(187,44,162)">var</span><span> </span>value:<span> </span><span style="color:rgb(112,61,170)">AnyObject</span><span> </span>{</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">           <span> </span><span style="color:rgb(187,44,162)">get</span><span> </span>{</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">               <span> </span><span style="color:rgb(187,44,162)">return</span><span> </span><span style="color:rgb(79,129,135)">_value</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">            }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">           <span> </span><span style="color:rgb(187,44,162)">set</span><span> </span>{</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>               <span> </span></span>// In all functions check that args declared as `T` are actually a `T` or a sub-type.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>               <span> </span></span>// Note: `is` only works with type literal and there is no `&gt;=` operator for types :(.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>               <span> </span></span>// `is` would need changing or `&gt;=` for types adding, nearest at moment `==`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)"><span>               <span> </span></span><span style="color:rgb(61,29,129)">precondition</span><span>(</span><span style="color:rgb(79,129,135)">T</span><span><span> </span>==<span> </span></span><span style="color:rgb(0,132,0)">/* &gt;= */</span><span><span> </span>newValue.</span><span style="color:rgb(187,44,162)">dynamicType</span><span>,<span> </span></span>&quot;Type of newValue,<span> </span><span>\</span>(<span>newValue.</span><span style="color:rgb(187,44,162)">dynamicType</span>), is not a sub-type of generic type T,<span> </span><span>\</span>(<span style="color:rgb(79,129,135)">T</span>)&quot;<span>)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">               <span> </span><span style="color:rgb(79,129,135)">_value</span><span> </span>= newValue</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">            }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">        <br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>       <span> </span></span>// Generated from `init(_ initialValue: T)` and noting that `T`&#39;s upper bound is `AnyObject`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">       <span> </span><span style="color:rgb(187,44,162)">init</span>(<span style="color:rgb(187,44,162)">_</span><span> </span>lowestCommonDeclaredT:<span> </span><span style="color:rgb(112,61,170)">AnyObject</span>.Type,<span> </span><span style="color:rgb(187,44,162)">_</span><span> </span>initialValue:<span> </span><span style="color:rgb(112,61,170)">AnyObject</span>) {</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">           <span> </span><span style="color:rgb(79,129,135)">T</span><span> </span>= lowestCommonDeclaredT</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">           <span> </span><span style="color:rgb(79,129,135)">_value</span><span> </span>= initialValue</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span>// Demonstrate that all `Box`es are the same size and therefore can be bitwise copied</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span>// Compiler supplies lowest-common, declared, generic type for all the `T`s in the `init` call.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span><span style="color:rgb(187,44,162)">var</span><span><span> </span>bT =<span> </span></span><span style="color:rgb(79,129,135)">BoxAnyObject</span><span>(</span><span style="color:rgb(79,129,135)">Top</span><span>.</span><span style="color:rgb(187,44,162)">self</span><span>,<span> </span></span><span style="color:rgb(79,129,135)">Top</span><span>())<span> </span></span>// In practice user would write `let bT = Box(Top())`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span><span style="color:rgb(79,129,135)">bT</span><span>.</span><span style="color:rgb(79,129,135)">T</span><span><span> </span></span>// Top.Type</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(61,29,129)"><span>   <span> </span></span>sizeofValue<span>(</span><span style="color:rgb(79,129,135)">bT</span><span>)<span> </span></span><span style="color:rgb(0,132,0)">// 16</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span><span style="color:rgb(187,44,162)">var</span><span><span> </span>bB =<span> </span></span><span style="color:rgb(79,129,135)">BoxAnyObject</span><span>(</span><span style="color:rgb(79,129,135)">Bottom</span><span>.</span><span style="color:rgb(187,44,162)">self</span><span>,<span> </span></span><span style="color:rgb(79,129,135)">Bottom</span><span>())<span> </span></span>// In practice user would write `let bB = Box(Bottom())`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span><span style="color:rgb(79,129,135)">bB</span><span>.</span><span style="color:rgb(79,129,135)">T</span><span><span> </span></span>// Bottom.Type</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(61,29,129)"><span>   <span> </span></span>sizeofValue<span>(</span><span style="color:rgb(79,129,135)">bB</span><span>)<span> </span></span><span style="color:rgb(0,132,0)">// 16</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span>// Demonstration covariance.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span><span style="color:rgb(79,129,135)">bT</span><span><span> </span>=<span> </span></span><span style="color:rgb(79,129,135)">bB</span><span><span> </span></span>// Compiler would check covariance of declared generic types.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span><span style="color:rgb(79,129,135)">bT</span><span>.</span><span style="color:rgb(79,129,135)">T</span><span><span> </span></span>// Bottom.Type</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span>// Demonstrate generic returned type</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span>// Compiler would add cast to declared, generic type.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span><span style="color:rgb(79,129,135)">bB</span><span>.</span><span style="color:rgb(79,129,135)">value</span><span><span> </span></span><span style="color:rgb(187,44,162)">as</span><span>!<span> </span></span><span style="color:rgb(79,129,135)">Bottom</span><span><span> </span></span>// In practice user would write `bB.value`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span>// Demonstrate type safety</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span><span style="color:rgb(79,129,135)">bT</span><span><span> </span>=<span> </span></span><span style="color:rgb(79,129,135)">BoxAnyObject</span><span>(</span><span style="color:rgb(79,129,135)">Top</span><span>.</span><span style="color:rgb(187,44,162)">self</span><span>,<span> </span></span><span style="color:rgb(79,129,135)">Top</span><span>())<span> </span></span>// In practice user would write `bT = Box(Top())`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">   <span> </span><span style="color:rgb(79,129,135)">bT</span>.<span style="color:rgb(79,129,135)">value</span><span> </span>=<span> </span><span style="color:rgb(79,129,135)">Top</span>()<span> </span><span style="color:rgb(0,132,0)">// OK</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span>// bT.value = Bottom() // Doesn&#39;t work at present because need `&gt;=` for types, but would work in practice</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span>   <span> </span></span>// bB.value = Top() // Runtime error - wrong type</div><div><br></div><div>The implications of this proposal are:</div><div><br></div><div>1. The compiler can statically type check a read from a stored property.</div><div>2. A write to a stored property is type checked at runtime.</div><div>3. Protocols can be made generic instead of having an associated type and then they become a proper type with dynamic dispatch.</div><div>4. Generic protocols can be a type just like non-generic protocols, structs, and classes and unlike associated type protocols that can only be a generic constraint.</div><div>5. The awkwardness of dealing with associated type generics is replaced by a more powerful and easier to understand semantic of a type, just like the other types.</div><div>6. There is a lot of ‘non-obvoius’, long code, for example `inits`, that use a `where` clause to constrain an associated type protocol, this would be unnecessary.</div><div>7. There are whole types, `AnySequence`, `AnyGenerator`, etc., that would be replaced by a generic protocols, `Sequence`, `Generator`, etc.</div><div><br></div><div>Advantages:</div><div><br></div><div>1. Covariant generics are a powerful addition to the language.</div><div>2. Generics’ invariance are inconsistent with the rest of the language.</div><div>3. Generic protocols would become a ‘proper’ type and you could have arrays and fields of a generic protocol.</div><div>4. There are many threads on swift-evolution looking at how protocols can be made into a ‘proper’ type or at least a concept that is easier to understand.</div><div><br></div><div>Compatibility:</div><div><br></div><div>1. This would be a major change since associated types in protocols would be replaced by generics.</div><div>2. The new implementation of generics might break some existing `struct` and `class` code, for example if it is dependent on the exact size of an object because the class will have extra fields, one for each generic type, and therefore will be larger.</div><div><br></div><div>Disadvantages:</div><div><br></div><div>1. Major change.</div><div>2. Object size increases.</div><div><br>Thanks in advance for any comments,</div><div><br></div><div>  — Howard.</div><div><br></div><div>PS This is part of a collection of proposals previously presented as “Protocols on Steroids”.</div><br><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=7XtDdMHRjqIUi4tzSjSp2pWQIyxYdP6woIWn4vwV5gfxpwEOVTzo92oepwWEcVNXvCsAW-2Forxg3RDuQnXnEKJE1s61ZQwLPbtLU8pGzxj-2FYRz7HG603-2BvteZzN-2FPTE-2BVvH2Y1MpBClLouTMgkPIrn3bmtRyaN-2BlVXaxdYx3nXLlGA923nAnKw6ygzx9hKAiqI7QEvEdSOrUWzbPB0oD6vLVU33TI1MC2Gqq7jZganWM-3D" alt="" width="1" height="1" border="0" style="min-height:1px!important;width:1px!important;border-width:0px!important;margin:0px!important;padding:0px!important"></div>_______________________________________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div></blockquote></div><br></div><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=ZEz4qHYnXhPr3bBPu-2FxP4tN3HfWKL-2FtJpqkQ0gkOVSCJDEhwwmTWIc-2FPZIHE-2BDgWzA3g-2BaJP6Sw8H28SvviIuJ2817Qb0JpvkK-2BlD32q7SAUi2tpKobxWWWuzmZK34QWPdnSF0T02rVkiqIh3fJsp2h29F4CLJjkrLOjsUiFetAIeWUYTrLOY-2Fh22qGItsbAlwpT8IMXEltTyCZ4TUX7OnIKNEGiEf8AlX3LUOB1nXM-3D" alt="" width="1" height="1" border="0" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;min-height:1px!important;width:1px!important;border-width:0px!important;margin:0px!important;padding:0px!important"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important"><span> </span>_______________________________________________</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">swift-evolution mailing list</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><a href="mailto:swift-evolution@swift.org" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank">swift-evolution@swift.org</a><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br></div></div></div></div></blockquote></div><br><br clear="all"><div><br></div></div></div><span class="HOEnZb"><font color="#888888">-- <br><div>  -- Howard.<br></div>
</font></span></div></div></div>
</blockquote></div><br></div>