<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">What if the “casted” value was treated as an implicitly-defined computed property? Something like this, maybe?<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">struct</span> Box&lt;T: AnyObject&gt; {</div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span> value: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">T</span></div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span>(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span> initialValue: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">T</span>) {</div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">value</span> = initialValue;</div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">} <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">as</span> T {</div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; get { <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return&nbsp;</span><span style="color: rgb(187, 44, 162);" class="">self</span>.<font color="#4f8187" class="">value</font>&nbsp;}</div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; set {&nbsp;<span style="color: rgb(187, 44, 162);" class="">self</span>.<font color="#4f8187" class="">value</font>&nbsp;= newValue }</div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div></div></div></div></div></div></blockquote><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; line-height: normal;"><br class=""></div><div class="" style="margin: 0px; line-height: normal;">The behavior is opt-in, simple, concise, and would allow for non-trivial cases if you were doing it for more than one type:</div><div class="" style="margin: 0px; line-height: normal;"><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="color: rgb(187, 44, 162);" class="">struct</span>&nbsp;DoubleBox&lt;T: AnyObject, U: AnyObject&gt; {</div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;<span style="color: rgb(187, 44, 162);" class="">var</span>&nbsp;t:&nbsp;<span style="color: rgb(112, 61, 170);" class="">T</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;<span style="color: rgb(187, 44, 162);" class="">var</span>&nbsp;u: <font color="#703daa" class="">U</font></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;<span style="color: rgb(187, 44, 162);" class="">init</span>(<span style="color: rgb(187, 44, 162);" class="">_</span>&nbsp;t:&nbsp;<span style="color: rgb(112, 61, 170);" class="">T, _: u: U</span>) {</div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: rgb(187, 44, 162);" class="">self</span>.<span style="color: rgb(79, 129, 135);" class="">t</span>&nbsp;= t</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: rgb(187, 44, 162);" class="">self</span>.<span style="color: rgb(79, 129, 135);" class="">u</span>&nbsp;= u</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}&nbsp;<span style="color: rgb(187, 44, 162);" class="">as</span>&nbsp;T {</div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;get {&nbsp;<span style="color: rgb(187, 44, 162);" class="">return&nbsp;</span><span style="color: rgb(187, 44, 162);" class="">self</span>.<font color="#4f8187" class="">t</font>&nbsp;}</div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; set {&nbsp;<span style="color: rgb(187, 44, 162);" class="">self</span>.<font color="#4f8187" class="">t</font>&nbsp;= newValue }</div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}&nbsp;<span style="color: rgb(187, 44, 162);" class="">as</span>&nbsp;U {&nbsp;<span style="color: rgb(187, 44, 162);" class="">return&nbsp;</span><span style="color: rgb(187, 44, 162);" class="">self</span>.<font color="#4f8187" class="">u&nbsp;</font>}&nbsp;<span style="color: rgb(0, 132, 0);" class="">// is read-only when accessed as a U</span></div></div></div></div></div></div></div></blockquote><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"></div></div></div></div></div></div></div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; line-height: normal;">- Dave</div><div class="" style="margin: 0px; line-height: normal;"><br class=""></div><div class="" style="margin: 0px; line-height: normal;">PS: Actually, in this case, since your boxed type has to be a class anyway (T: AnyObject vs T) you can *almost* do this now, if you’re willing to write some boilerplate and kind of abuse the Objective-C Bridging system:</div></div></div></div></div></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; line-height: normal;"><div style="margin: 0px; line-height: normal; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">extension</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Box</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">: </span>_ObjectiveCBridgeable<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> {</span></div></div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><div style="margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">typealias</span> _ObjectiveCType = <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T&nbsp;</span><span style="color: rgb(0, 132, 0);" class="">// the protocol says _ObjectiveCType: AnyObject, so any class will do</span></div></div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><p style="margin: 0px; line-height: normal; min-height: 13px;" class="">&nbsp;&nbsp; &nbsp;</p></div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><div style="margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">static</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> _isBridgedToObjectiveC() -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span> {&nbsp;<span style="color: rgb(187, 44, 162);" class="">return</span> <span style="color: rgb(187, 44, 162);" class="">true&nbsp;</span>}</div></div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><div style="margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">static</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> _getObjectiveCType() -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Any</span>.Type {&nbsp;<span style="color: rgb(187, 44, 162);" class="">return</span> <span style="color: rgb(79, 129, 135);" class="">_ObjectiveCType</span>.<span style="color: rgb(187, 44, 162);" class="">self&nbsp;</span>}</div></div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><div style="margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">static</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> _forceBridgeFromObjectiveC(source: <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">_ObjectiveCType</span>, <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">inout</span> result: <font color="#4f8187" class="">Box</font>?) {&nbsp;<span style="color: rgb(187, 44, 162);" class="">result = </span><font color="#4f8187" class="">Box</font>(source) }</div></div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><div style="margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">static</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> _conditionallyBridgeFromObjectiveC(source: <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">_ObjectiveCType</span>, <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">inout</span> result: <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Box</span>?) -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span> {</div></div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><div style="margin: 0px; line-height: normal; color: rgb(187, 44, 162);" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: rgb(49, 89, 93);" class="">_forceBridgeFromObjectiveC</span>(source, result: &amp;result)</div></div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><div style="margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: rgb(187, 44, 162);" class="">return</span> result != <span style="color: rgb(187, 44, 162);" class="">nil</span></div></div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><div style="margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; }</div></div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><div style="margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> _bridgeToObjectiveC() -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">_ObjectiveCType</span> {&nbsp;<span style="color: rgb(187, 44, 162);" class="">return&nbsp;</span><span style="color: rgb(187, 44, 162);" class="">self</span>.<font color="#4f8187" class="">value&nbsp;</font>}</div></div></div></div></div></div></div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><div style="margin: 0px; line-height: normal;" class="">}</div></div></div></div></div></div></div></div></blockquote><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; line-height: normal;"><div class="">Then this works now in the current version of Xcode:</div></div></div></div></div></div></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; line-height: normal;"><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> box = <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Box</span>(Bottom())</div><div style="margin: 0px; line-height: normal;" class=""><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);" class="">let</span><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp;bottom =&nbsp;</span></font><font color="#4f8187" face="Menlo" style="font-family: Menlo; font-size: 12px;" class=""><span style="font-size: 11px;" class="">box</span></font><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp;</span></font><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);" class="">as</span><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp;</span></font><font color="#4f8187" face="Menlo" style="font-family: Menlo; font-size: 12px;" class=""><span style="font-size: 11px;" class="">Bottom</span></font></div></div></div></div></div></div></div></div></blockquote><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; line-height: normal;"><br class=""></div><div class="" style="margin: 0px; line-height: normal;">Although, I’m not sure how long it will keep working, since&nbsp;<span style="color: rgb(112, 61, 170);" class="">_ObjectiveCBridgeable</span>&nbsp;should probably constrain&nbsp;_ObjectiveCType to NSObject rather than AnyObject. Also, going the other way — converting from Bottom to Box&lt;Bottom&gt; — using this technique gives an error. It works with the non-generic types I was playing around with earlier, though… Maybe it’s something to do with compiler assumptions and differences between Swift’s and Objective-C’s generics system, or maybe I’m getting the function signatures close enough to satisfy the protocol requirements but somehow subtly wrong (which wouldn’t surprise me at all… sometimes I have trouble getting the details right when I’m dealing with generics in protocols).</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><br class=""></div></div></div></div></div></div></div><div class=""><div><blockquote type="cite" class=""><div class="">On Jan 12, 2016, at 16:33, Simon Pilkington via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">The problem is that conceptually and behaviourally Box&lt;Bottom&gt; *is indeed not* a Box&lt;Top&gt; and cannot be treated the same as one. The proposal attempts to get around this difference with a runtime failure but this would result in very fragile code - you get passed a Box&lt;Top&gt; and want to pass it a subclass of Top, will it succeed, who knows. You probably would be able to check the types but the complier wouldn’t highlight that this is an operation that could potentially fail.</div><div class=""><br class=""></div><div class="">This seems to be very much against Swift’s goal of safety being enforced by the compiler as much as possible.</div><div class=""><br class=""></div><div class="">Java uses the wildcard syntax to highlight this conceptual and behavioural difference - Box&lt;Bottom&gt; is not covariant with Box&lt;Top&gt; but rather with Box&lt;? extends Top&gt;. The compiler can then enforce that a programmer doesn’t try to pass an incompatible type to a variable of such type. Even though this is a complication to the language (many Java programmers struggle with correctly using the wildcard syntax) I don’t see covariance for generics being added to Swift in a robust manner without some kind of similar syntax.</div><div class=""><br class=""></div><div class="">-Simon</div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 12 Jan 2016, at 8:45 PM, Howard Lovatt via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">Currently you generics are invariant whereas function&nbsp;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;" class=""><font face="Menlo" class=""><span style="font-size: 11px;" class=""><br class=""></span></font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">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);" class=""><span style="" class=""><br class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp;&nbsp; &nbsp;</span>// Current system</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">class</span> Top {}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">class</span> Bottom: <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Top</span> {}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">struct</span> Box&lt;T: AnyObject&gt; {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span> value: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">T</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span>(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span> initialValue: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">T</span>) {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">value</span> = initialValue;</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> boxB = <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Box</span>(<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Bottom</span>())</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; </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;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class="">The key point is although `Bottom` '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;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class="">I am suggesting:</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class="">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;" class="">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;" class="">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;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; </span>// Proposal:</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; </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);" class=""><span style="" class="">&nbsp; &nbsp; </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);" class=""><span style="" class="">&nbsp; &nbsp; </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;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; </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);" class=""><span style="" class="">&nbsp; &nbsp; </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;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">struct</span> BoxAnyObject {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; </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);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="" class=""> T: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">AnyObject</span><span style="" class="">.Type </span>// Store the actual type.</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class="">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;<br class="webkit-block-placeholder"></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span>// Generated from stored property `var value: T` and noting that `T`'s upper bound is `AnyObject`.</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">private</span><span style="" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span><span style="" class=""> _value: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">AnyObject</span><span style="" class=""> </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;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span> value: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">AnyObject</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">get</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">_value</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">set</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </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);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </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);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </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);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">precondition</span><span style="" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span><span style="" class=""> == </span><span style="font-variant-ligatures: no-common-ligatures; color: #008400" class="">/* &gt;= */</span><span style="" class=""> newValue.</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">dynamicType</span><span style="" class="">, </span>"Type of newValue, <span style="" class="">\</span>(<span style="" class="">newValue.</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">dynamicType</span>), is not a sub-type of generic type T, <span style="" class="">\</span>(<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span>)"<span style="" class="">)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">_value</span> = newValue</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class="">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;<br class="webkit-block-placeholder"></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span>// Generated from `init(_ initialValue: T)` and noting that `T`'s upper bound is `AnyObject`.</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span>(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span> lowestCommonDeclaredT: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">AnyObject</span>.Type, <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span> initialValue: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">AnyObject</span>) {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span> = lowestCommonDeclaredT</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">_value</span> = initialValue</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; </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);" class=""><span style="" class="">&nbsp; &nbsp; </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);" class=""><span style="" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span><span style="" class=""> bT = </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">BoxAnyObject</span><span style="" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Top</span><span style="" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">self</span><span style="" class="">, </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Top</span><span style="" class="">()) </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);" class=""><span style="" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">bT</span><span style="" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span><span style="" class=""> </span>// Top.Type</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(61, 29, 129);" class=""><span style="" class="">&nbsp; &nbsp; </span>sizeofValue<span style="" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">bT</span><span style="" class="">) </span><span style="font-variant-ligatures: no-common-ligatures; color: #008400" class="">// 16</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span><span style="" class=""> bB = </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">BoxAnyObject</span><span style="" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Bottom</span><span style="" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">self</span><span style="" class="">, </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Bottom</span><span style="" class="">()) </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);" class=""><span style="" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">bB</span><span style="" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span><span style="" class=""> </span>// Bottom.Type</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(61, 29, 129);" class=""><span style="" class="">&nbsp; &nbsp; </span>sizeofValue<span style="" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">bB</span><span style="" class="">) </span><span style="font-variant-ligatures: no-common-ligatures; color: #008400" class="">// 16</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; </span>// Demonstration covariance.</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">bT</span><span style="" class=""> = </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">bB</span><span style="" class=""> </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);" class=""><span style="" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">bT</span><span style="" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span><span style="" class=""> </span>// Bottom.Type</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; </span>// Demonstrate generic returned type</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; </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);" class=""><span style="" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">bB</span><span style="" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">value</span><span style="" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">as</span><span style="" class="">! </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Bottom</span><span style="" class=""> </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;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; </span>// Demonstrate type safety</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">bT</span><span style="" class=""> = </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">BoxAnyObject</span><span style="" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Top</span><span style="" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">self</span><span style="" class="">, </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Top</span><span style="" class="">()) </span>// In practice user would write `bT = Box(Top())`.</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">bT</span>.<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">value</span> = <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Top</span>() <span style="font-variant-ligatures: no-common-ligatures; color: #008400" class="">// OK</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; </span>// bT.value = Bottom() // Doesn'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);" class=""><span style="" class="">&nbsp; &nbsp; </span>// bB.value = Top() // Runtime error - wrong type</div><div class=""><br class=""></div><div class="">The implications of this proposal are:</div><div class=""><br class=""></div><div class="">1. The compiler can statically type check a read from a stored property.</div><div class="">2. A write to a stored property is type checked at runtime.</div><div class="">3. Protocols can be made generic instead of having an associated type and then they become a proper type with dynamic dispatch.</div><div class="">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 class="">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 class="">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 class="">7. There are whole types, `AnySequence`, `AnyGenerator`, etc., that would be replaced by a generic protocols, `Sequence`, `Generator`, etc.</div><div class=""><br class=""></div><div class="">Advantages:</div><div class=""><br class=""></div><div class="">1. Covariant generics are a powerful addition to the language.</div><div class="">2. Generics’ invariance are inconsistent with the rest of the language.</div><div class="">3. Generic protocols would become a ‘proper’ type and you could have arrays and fields of a generic protocol.</div><div class="">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 class=""><br class=""></div><div class="">Compatibility:</div><div class=""><br class=""></div><div class="">1. This would be a major change since associated types in protocols would be replaced by generics.</div><div class="">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 class=""><br class=""></div><div class="">Disadvantages:</div><div class=""><br class=""></div><div class="">1. Major change.</div><div class="">2. Object size increases.</div><div class=""><br class="">Thanks in advance for any comments,</div><div class=""><br class=""></div><div class="">&nbsp; — Howard.</div><div class=""><br class=""></div><div class="">PS This is part of a collection of proposals previously presented as “Protocols on Steroids”.</div>
<br class="">
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=t1lXJ9jBaqmhI-2F639qqRIv6GBQuIzl35AVl5PWMKokCrmW5RYfNBeoAeoL3QdFfVx3rPNQq53b3E-2BXtIrfGZD6BWDbeHevI6aXpB216n-2BXAzdhfAiJOmo2pYaWogM-2BA6FvDS-2BoqwOTpWlb18dvbbNvFImgTJnxidNrNIMC2nI3XrvpMWHLepYAMFhpLnSg14aCNI-2Fw1iOcR5Jy1UXBsVx7H49Ko6rxAcKzwWU-2BzhB5Y-3D" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;" class="">
</div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=mnFI6pg-2FTCMHnIXafbniMQOkvAOxgYUwbalcxNWA5RfPvMpvVbdtyMhXuvviEDSc-2FoHPJu-2BYRrgZpUVCqC7FXqeBNEem2V1CftO637PqkM5h4nLQvjQiiU3g-2BOUra4J2X5pFsT-2FzIgDxVgnXkvEj281CiaVty-2B17G5864QkHHTtNMNbA1Ca0hyE2dGnB9xOIw3mSMCrRs-2Bo0j-2FYHJofYeVUy0bPwEpBKiyZ-2BFTm7mtE-3D" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;" class="">
</div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></div></body></html>