<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 24, 2016, at 12:07 PM, Joe Groff 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=""><div class="">'Any' is definitely a better name, but I think this is still syntax only a compiler can love. If we're going to repaint this bikeshed, I think we should also consider as an alternative some form of infix syntax for composing constraints. Rust uses `P1 + P2`, and various C++ proposals have suggested `P1 &amp;&amp; P2`. Some pros(+) and cons(-) I can see with this approach:<br class=""><br class="">+ Infix notation works not only in type position, but constraint position as well, providing a nicer way to express multiple type variable constraints:<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>var x: P &amp;&amp; Q<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func foo&lt;T: P &amp;&amp; Q, U&gt;(x: T)<br class=""><br class="">+ Infix notation feels subjectively lighter, being less nesty and angle-bracket-blinding. Compare the above with:<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>var x: Any&lt;P, Q&gt;<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func foo&lt;T: Any&lt;P,Q&gt;, U&gt;(x: T)<br class=""><br class=""></div></div></blockquote><div><br class=""></div><div>Perhaps just a comma separated list like a&nbsp;<font color="#808080" face="Helvetica, Arial, sans-serif" class=""><span style="font-size: 14px;" class=""><i class="">type-inheritance-clause</i></span></font>, using parenthesis for disambiguation?</div><div><br class=""></div><div>var x: P, Q</div><div>func foo&lt;(T: P, Q), U&gt;</div><div><br class=""></div><div>or</div><div>&nbsp;</div><div><div>func foo&lt;T: (P, Q), U&gt;</div></div><div><br class=""></div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div class="">Particularly in the second declaration, I find the nested angle brackets and comma delimiters to be hard to visually parse.<br class=""><br class="">± Like 'Any', an infix operator doesn't pass judgment on what kinds of constraint is being applied, so it naturally extends to expressing class-with-protocol constraints.<br class=""><br class="">- Infix notation doesn't provide an obvious place for generalized existentials to hang secondary constraints. The angle brackets for Any provide an enclosed syntactic space we can easily stuff a 'where' clause:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func sum(_ collection: Any&lt;Sequence where Element == Int&gt;) -&gt; Int { ... }<br class=""><br class="">(though this notation still feels heavy and awkward to me).<br class=""><br class="">- The bracketing of `Any` might let us address the curious case of protocol vs existential metatypes in a better way. Right now, the static metatype for a protocol type (the type of `P.self`) is spelled `P.Protocol`, and the dynamic metatype for any type conforming to the protocol (the erased type of `T.self` where T: P) is spelled `P.Type`. Unintuitively, when a protocol type is substituted into `T.Type` in a generic context, you get the static type `P.Protocol` rather than `P.Type`, for soundness reasons:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func staticType&lt;T&gt;(of _: T) -&gt; T.Type { return T.self }<br class=""><br class="">This substitution behavior could be made clearer if we moved a dynamic metatype's `.Type` into the Any brackets, so that `Any&lt;P.Type&gt;` would be the dynamic metatype of any type conforming to P, and `Any&lt;P&gt;.Type` would be the static metatype of the type `Any&lt;P&gt;`. Infix notation doesn't provide an opportunity to make this clarification.<br class=""><br class="">- A few people have also noted the similarity between Any&lt;...&gt; and normal generic types. This is potentially confusing today, but with enough magic language features from the future, Any *could* conceivably be made a library feature in the fullness of time:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// Let's say 'protocol' constraints indicate second-order constraint variables:<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>enum Any&lt;Constraints: protocol&gt; {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>// And we have GADTs:<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>case value&lt;T: Constraints&gt;(T)<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// And we have user-defined value subtyping:<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>extension &lt;Constraints: protocol, T: Constraints&gt; T: Any&lt;Constraints&gt; { ... }<br class=""><br class="">-Joe<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="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></div></blockquote></div><br class=""></body></html>