<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=""><div><blockquote type="cite" class=""><div class="">On Dec 8, 2015, at 11:47 PM, Simon Pilkington via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> 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="">Hi,</div><div class=""><br class=""></div><div class="">Is providing Covariance and Contravariance[1] of generics going to be part of the work on generics for Swift 3? I am sure this topic has come up within the core team and I was wondering what their opinion on the topic was.</div><div class=""><br class=""></div><div class="">I can see this as beneficial as it would allow the compiler - in conjunction with type inference - to retain more type information and hence allow code be more type safe. For example -</div><div class=""><br class=""></div><div class=""><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="">class</span> ConcreteClass<GenType : GenericType> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <font color="#bb2ca2" class="">...</font></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""> <br class="webkit-block-placeholder"></div><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="">func</span> getFunction() -> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">GenType</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <font color="#bb2ca2" class="">...</font></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""> <br class="webkit-block-placeholder"></div><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="">func</span> putFunction(input: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">GenType</span>) -> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span> {</div><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="">return</span> ...</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""> <br class="webkit-block-placeholder"></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</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=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span> GenericType {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <font color="#bb2ca2" class="">...</font></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</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=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">class</span> GenericType1 : <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">GenericType</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <font color="#bb2ca2" class="">...</font></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</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=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">class</span> GenericType2 : <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">GenericType</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <font color="#bb2ca2" class="">...</font></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</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(79, 129, 135);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="" class=""> array = [</span>ConcreteClass<span style="" class=""><</span>GenericType2<span style="" class="">>(...</span><span style="" class="">), </span>ConcreteClass<span style="" class=""><</span>GenericType1<span style="" class="">>(...</span><span style="" class="">)]</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=""><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">let x : </span>GenericType = <span style="color: rgb(79, 129, 135);" class="">array</span>[<span style="color: rgb(39, 42, 216);" class="">0</span>].getFunction() // this would compile as array would be of type ConcreteClass<types that extend GenericType></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> // currently array is of type AnyObject so this line doesn’t compile</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">array</span>[<span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">0</span>].putFunction(…) // this would still not compile as it would break type guarantees</div></div><div class=""><br class=""></div><div class="">As a downside I can see it as making generics more complex and difficult to understand. On balance I think probably the benefit in improved type safety is worth it but I was interested in what others thought.</div></div></div></blockquote><div><br class=""></div></div>One challenge here is that subtyping in Swift doesn’t mean equivalence of representation. For example, Int is a subtype of Int?, but the later requires extra space to store in memory. So while it would make sense to allow, say, [Int] to be a subtype of [Int?], the actual conversion at runtime wouldn’t be trivial — we’d either need to eagerly apply the element-wise transform, or Array would need some ability to apply it lazily. Both come with fairly serious performance costs.<div class=""><br class=""></div><div class="">John.</div></body></html>