<html><head><style>body{font-family:Helvetica,Arial;font-size:13px}</style></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><blockquote type="cite" class="clean_bq"><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><blockquote type="cite" class=""><div class=""><div id="bloop_customfont" class="" style="font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; margin: 0px;">So without any initial constraints how would one use this generic function??</div><div id="bloop_customfont" class="" style="font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; margin: 0px;"><br class=""></div><div id="bloop_customfont" class="" style="font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; margin: 0px;">extension UIButton: ProtocolA {}</div><div id="bloop_customfont" class="" style="font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; margin: 0px;"><br class=""></div><div id="bloop_customfont" class="" style="font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; margin: 0px;">let button = UIButton()</div><div id="bloop_customfont" class="" style="font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; margin: 0px;">let shadowedButton: ProtocolA = UIButton()</div><div id="bloop_customfont" class="" style="font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; margin: 0px;"><br class=""></div><div id="bloop_customfont" class="" style="font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; margin: 0px;">// creates a set of a least one element if the generic type could be inferred</div><div id="bloop_customfont" class="" style="font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; margin: 0px;">func unionIfPossible&lt;T, U&gt;(_ a: T, _ b: U) -&gt; Set&lt;Any&lt;T, U&gt;&gt;? { /* merge somehow if possible */ }</div></div></blockquote><div><br class=""></div><div>You would not be able to form Any&lt;T, U&gt; here because T and U are generic arguments unknown. &nbsp;We don’t accept those, only `class`, specific classes, and specific protocols (and recursively, other Any).</div></div></blockquote><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><br></div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;">Why would Any&lt;…&gt; does not work with the generic system here? To me it makes no sense, I as a developer would assume I can use a generic Type anywhere a type can be used (protocols and their associated types are a special case).</div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><br></div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;">I would assume that:</div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><br></div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;">func foo&lt;T: UIView&gt;(value: Any&lt;T, SomeProtocol&gt;)</div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><br></div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;">should be equal to (without the need of generics):</div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><br></div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;">func foo(value: Any&lt;UIView, SomeProtocol&gt;)</div><br><div><blockquote type="cite" class="clean_bq" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><blockquote type="cite" class=""><div class=""><div id="bloop_customfont" class="" style="font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; margin: 0px;"><br class="Apple-interchange-newline">// this should be valid because the compiler will assume Any&lt;UIView, ProtocolA&gt; where T == UIView and U == ProtocolA</div><div id="bloop_customfont" class="" style="font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; margin: 0px;">let merged_1: Set&lt;Any&lt;UIView, ProtocolA&gt;&gt; = unionIfPossible( /* UIView subtype */ button, /* ProtocolA */ shadowedButton)&nbsp;</div><div id="bloop_customfont" class="" style="font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; margin: 0px;"><br class=""></div><div id="bloop_customfont" class="" style="font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; margin: 0px;"><div id="bloop_customfont" class="" style="margin: 0px;">// this won’t be possible because of the restriction</div><div id="bloop_customfont" class="" style="margin: 0px;">let merged_2: Set&lt;Any&lt;UIView, ProtocolA&gt;&gt; = unionIfPossible(shadowedButton, button)&nbsp;</div><div id="bloop_customfont" class="" style="margin: 0px;"><br class=""></div><div id="bloop_customfont" class="" style="margin: 0px;">Any&lt;UIView, ProtocolA&gt; != Any&lt;ProtocolA, UIView&gt; isn’t right. Sure it may feel right for readability but the types should be equal.</div><div id="bloop_customfont" class="" style="margin: 0px;"><br class=""></div><div id="bloop_customfont" class="" style="margin: 0px;">"Can be any class type that is a UIView or a subclass of UIView,&nbsp;that also conforms to ProtocolA.“ == "Type that conforms to&nbsp;ProtocolA&nbsp;and that is a UIView or a subclass of UIView.“</div><div id="bloop_customfont" class="" style="margin: 0px;"><br class=""></div><div id="bloop_customfont" class="" style="margin: 0px;">This is also a nesting problem where you will be forced to choose the right place inside the angle brackets where to add a nested `Any&lt;…&gt;`.</div><div id="bloop_customfont" class="" style="margin: 0px;"><br class=""></div><div id="bloop_customfont" class="" style="margin: 0px;">class A: ClassB, ProtocolA {}</div><div id="bloop_customfont" class="" style="margin: 0px;"><br class=""></div><div id="bloop_customfont" class="" style="margin: 0px;">Any&lt;A, Any&lt;ClassB, ProtocolA&gt;&gt; == A != Any&lt;Any&lt;ClassB, ProtocolA&gt;, A&gt; == Any&lt;ClassB, ProtocolA, A&gt; which should be reorder by the compiler and inferred as A</div></div></div></blockquote><div><br class=""></div><div>`Any&lt;Any&lt;ClassB, ProtocolA&gt;, A&gt;` is not allowed because if a class is provided it must come first.</div><div><br class=""></div><div>`<span class="">Any&lt;ClassB, ProtocolA, A&gt;` is not allowed because it contains more than one class.</span></div></div></blockquote></div><p>Not true, take a look at the nested section of the proposal again.</p><p>We discussed that this is valid:</p><pre style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal; color: rgb(51, 51, 51);"><span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// Allowed, but pointless.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// Identical to Any&lt;ProtocolA, ProtocolB&gt;</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> b <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Any</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">&lt;</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Any</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">&lt;</span>ProtocolA, ProtocolB<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">&gt;&gt;</span></pre><div><br class="Apple-interchange-newline"></div></div> <div>This implies that also this would be valid:</div><div><br></div><div>Any&lt;Any&lt;ClassA, ProtocolA&gt;&gt; inferred as Any&lt;ClassA, ProtocolA&gt;</div><div><br></div><div>There is another example:</div><div><br></div><div><pre style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal; color: rgb(51, 51, 51);"><span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// Can be any type that is a UITableView conforming to ProtocolA.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// UITableView is the most specific class, and it is a subclass of the other</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// two classes.</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> a <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Any</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">&lt;</span>UIScrollView, <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Any</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">&lt;</span>UITableView, <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Any</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">&lt;</span>UIView, ProtocolA&gt;&gt;&gt;</pre></div><div><br></div><div>Which followed by the mentioned rule can als be:</div><div><br></div><div>Any&lt;UIScrollView, UITableView, Any&lt;UIView, ProtocolA&gt;&gt; or</div><div>Any&lt;UIScrollView, UITableView, UIView, ProtocolA&gt;</div><div><br></div><div>This would force us to allow multiple classes inside Any&lt;…&gt; if there is a inheritance relationship between them.</div><div><br></div><div>And because this is a inheritance relationship it can be simplified to:</div><div><br></div><div>Any&lt;UITableView, ProtocolA&gt; which is valid.&nbsp;</div><div><br></div><div>And by the way since the order in your proposal would matter, this example won’t work at all, because its not:</div><div><br></div><div>Any&lt;UITableView, Any&lt;UIScrollView, Any&lt;UIView, ProtocolA&gt;&gt;&gt;&nbsp;</div><div><br></div>In my proposal I explicitly banned multiple reference types and inheritance branches like this. I would need to simplify that type to Any&lt;UITableView, ProtocolA&gt; by myself.<div>Ingeneral this is a good idea, but it makes nesting (with typealiases) almost impossible, when there are some relationship like in the above example.</div><div><br></div><div><br> <div id="bloop_sign_1463603456016581120" class="bloop_sign"><div style="font-family:helvetica,arial;font-size:13px">--&nbsp;<br>Adrian Zubarev<br>Sent with Airmail</div></div></div></body></html>