<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On May 18, 2016, at 4:17 PM, Austin Zheng 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=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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;" class="">I'm not sure what your objections actually are, but my responses are inline.<br class=""></div></div></blockquote><div><br class=""></div><div>Your responses are exactly what mine would be. For a second I was worried that I missed something when reading the latest draft! :)</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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;" class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, May 18, 2016 at 1:57 PM, Adrian Zubarev via swift-evolution<span class="Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>></span><span class="Apple-converted-space"> </span>wrote:<br class=""><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;" class=""><div style="font-family: Helvetica, Arial; font-size: 13px; margin: 0px;" class=""><span class=""><blockquote type="cite" class=""><div style="word-wrap: break-word;" class=""><blockquote type="cite" class=""><div class=""><div style="margin: 0px;" class="">So without any initial constraints how would one use this generic function??</div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class="">extension UIButton: ProtocolA {}</div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class="">let button = UIButton()</div><div style="margin: 0px;" class="">let shadowedButton: ProtocolA = UIButton()</div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class="">// creates a set of a least one element if the generic type could be inferred</div><div style="margin: 0px;" class="">func unionIfPossible<T, U>(_ a: T, _ b: U) -> Set<Any<T, U>>? { /* merge somehow if possible */ }</div></div></blockquote><div class=""><br class=""></div><div class="">You would not be able to form Any<T, U> here because T and U are generic arguments unknown. We don’t accept those, only `class`, specific classes, and specific protocols (and recursively, other Any).</div></div></blockquote><div style="font-family: Helvetica, Arial; font-size: 13px; margin: 0px;" class=""><br class=""></div></span><div style="font-family: Helvetica, Arial; font-size: 13px; margin: 0px;" class="">Why would Any<…> 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></div></blockquote><div class=""><br class=""></div><div class="">Because what existentials are trying to model and what generic type parameters are trying to model are two different things. You already cannot use arbitrary types within a Any<> existential as the proposal stands.</div><div class=""><br class=""></div><div class="">This doesn't currently work in Swift, and it shouldn't: "func foo<A, B>() -> protocol<A, B>". There is no useful way to generically compose instances of two protocol types at runtime to form an instance of a type that conforms to both protocols, like there is a way to compose instances of two types to form a tuple containing those types. Therefore, writing a generic function to do this makes no sense.</div><div class=""><br class=""></div><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;" class=""><div style="font-family: Helvetica, Arial; font-size: 13px; margin: 0px;" class=""><div style="font-family: Helvetica, Arial; font-size: 13px; margin: 0px;" class=""><br class=""></div><div style="font-family: Helvetica, Arial; font-size: 13px; margin: 0px;" class="">I would assume that:</div><div style="font-family: Helvetica, Arial; font-size: 13px; margin: 0px;" class=""><br class=""></div><div style="font-family: Helvetica, Arial; font-size: 13px; margin: 0px;" class="">func foo<T: UIView>(value: Any<T, SomeProtocol>)</div><div style="font-family: Helvetica, Arial; font-size: 13px; margin: 0px;" class=""><br class=""></div><div style="font-family: Helvetica, Arial; font-size: 13px; margin: 0px;" class="">should be equal to (without the need of generics):</div><div style="font-family: Helvetica, Arial; font-size: 13px; margin: 0px;" class=""><br class=""></div><div style="font-family: Helvetica, Arial; font-size: 13px; margin: 0px;" class="">func foo(value: Any<UIView, SomeProtocol>)</div><span class=""><br class=""><div class=""><blockquote type="cite" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div style="word-wrap: break-word;" class=""><blockquote type="cite" class=""><div class=""><div style="margin: 0px;" class=""><br class="">// this should be valid because the compiler will assume Any<UIView, ProtocolA> where T == UIView and U == ProtocolA</div><div style="margin: 0px;" class="">let merged_1: Set<Any<UIView, ProtocolA>> = unionIfPossible( /* UIView subtype */ button, /* ProtocolA */ shadowedButton) </div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class=""><div style="margin: 0px;" class="">// this won’t be possible because of the restriction</div><div style="margin: 0px;" class="">let merged_2: Set<Any<UIView, ProtocolA>> = unionIfPossible(shadowedButton, button) </div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class="">Any<UIView, ProtocolA> != Any<ProtocolA, UIView> isn’t right. Sure it may feel right for readability but the types should be equal.</div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class="">"Can be any class type that is a UIView or a subclass of UIView, that also conforms to ProtocolA.“ == "Type that conforms to ProtocolA and that is a UIView or a subclass of UIView.“</div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class="">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<…>`.</div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class="">class A: ClassB, ProtocolA {}</div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class="">Any<A, Any<ClassB, ProtocolA>> == A != Any<Any<ClassB, ProtocolA>, A> == Any<ClassB, ProtocolA, A> which should be reorder by the compiler and inferred as A</div></div></div></blockquote><div class=""><br class=""></div><div class="">`Any<Any<ClassB, ProtocolA>, A>` is not allowed because if a class is provided it must come first.</div><div class=""><br class=""></div><div class="">`<span class="">Any<ClassB, ProtocolA, A>` is not allowed because it contains more than one class.</span></div></div></blockquote></div></span><p class="">Not true, take a look at the nested section of the proposal again.</p><p class="">We discussed that this is valid:</p><pre style="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);" class=""><span style="color: rgb(150, 152, 150);" class="">// Allowed, but pointless.</span>
<span style="color: rgb(150, 152, 150);" class="">// Identical to Any<ProtocolA, ProtocolB></span>
<span style="color: rgb(167, 29, 93);" class="">let</span> b <span style="color: rgb(167, 29, 93);" class="">:</span> <span style="color: rgb(0, 134, 179);" class="">Any</span><span style="color: rgb(167, 29, 93);" class=""><</span><span style="color: rgb(0, 134, 179);" class="">Any</span><span style="color: rgb(167, 29, 93);" class=""><</span>ProtocolA, ProtocolB<span style="color: rgb(167, 29, 93);" class="">>></span></pre><div class=""><br class=""></div></div><div class="">This implies that also this would be valid:</div><div class=""><br class=""></div><div class="">Any<Any<ClassA, ProtocolA>> inferred as Any<ClassA, ProtocolA></div></div></blockquote><div class=""><br class=""></div><div class="">Yes, this is valid.</div><div class=""> </div><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;" class=""><div class=""><br class=""></div><div class="">There is another example:</div><div class=""><br class=""></div><div class=""><pre style="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);" class=""><span style="color: rgb(150, 152, 150);" class="">// Can be any type that is a UITableView conforming to ProtocolA.</span>
<span style="color: rgb(150, 152, 150);" class="">// UITableView is the most specific class, and it is a subclass of the other</span>
<span style="color: rgb(150, 152, 150);" class="">// two classes.</span>
<span style="color: rgb(167, 29, 93);" class="">let</span> a <span style="color: rgb(167, 29, 93);" class="">:</span> <span style="color: rgb(0, 134, 179);" class="">Any</span><span style="color: rgb(167, 29, 93);" class=""><</span>UIScrollView, <span style="color: rgb(0, 134, 179);" class="">Any</span><span style="color: rgb(167, 29, 93);" class=""><</span>UITableView, <span style="color: rgb(0, 134, 179);" class="">Any</span><span style="color: rgb(167, 29, 93);" class=""><</span>UIView, ProtocolA>>></pre></div><div class=""><br class=""></div><div class="">Which followed by the mentioned rule can als be:</div><div class=""><br class=""></div><div class="">Any<UIScrollView, UITableView, Any<UIView, ProtocolA>> or</div><div class="">Any<UIScrollView, UITableView, UIView, ProtocolA></div><div class=""><br class=""></div><div class="">This would force us to allow multiple classes inside Any<…> if there is a inheritance relationship between them.</div></div></blockquote><div class=""><br class=""></div><div class="">Yes. As explained in the proposal, there is already a way to handle resolving the single 'effective' class constraint. You can only 'explicitly' declare one class constraint, but you can pull in other class constraints from nested existentials for the sake of making composition easier. In the end it doesn't matter, because if the class constraints don't form a valid inheritance hierarchy the compiler will complain, and if they do the most specific type will be chosen.</div><div class=""> </div><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;" class=""><div class=""><br class=""></div><div class="">And because this is a inheritance relationship it can be simplified to:</div><div class=""><br class=""></div><div class="">Any<UITableView, ProtocolA> which is valid. </div><div class=""><br class=""></div><div class="">And by the way since the order in your proposal would matter, this example won’t work at all, because its not:</div><div class=""><br class=""></div><div class="">Any<UITableView, Any<UIScrollView, Any<UIView, ProtocolA>>> </div></div></blockquote><div class=""><br class=""></div><div class="">The order does<span class="Apple-converted-space"> </span><b class="">not</b> affect the semantic meaning of the existential. There is a section in the proposal on how existentials are conceptually 'reduced' from whatever form they take when the programmer types them in, please read it. I am not proposing a macro system. The compiler does not do textual replacement in order to flatten nested existential definitions.</div><div class=""><br class=""></div><div class="">This is also why it makes no sense to have a generic "Any<T, U>", because such a type is identical to "Any<U, T>", which is not true for any other generic type or aggregate type in Swift.</div><div class=""> </div><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;" class=""><div class=""><br class=""></div>In my proposal I explicitly banned multiple reference types and inheritance branches like this. I would need to simplify that type to Any<UITableView, ProtocolA> by myself.<div class="">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><span class=""><div class=""><br class=""></div><div class=""><br class=""><div class=""><div style="font-family: helvetica, arial; font-size: 13px;" class="">-- <br class="">Adrian Zubarev<br class="">Sent with Airmail</div></div></div></span></div><br class="">_______________________________________________<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" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""><br class=""></blockquote></div><br class=""></div></div><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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; float: none; display: inline !important;" class="">_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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; float: none; display: inline !important;" class="">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; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><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; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">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; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><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; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br class=""></body></html>