<div dir="ltr">I put together the skeleton of a proposal detailing enhancements to how associated types can be referenced in Swift 3+. It&#39;s certainly not ready for submission, but I think it gets across my ideas pretty well. Would love to gather feedback and especially improvements.<div><br></div><div>Be unsparing; whatever form this feature takes will profoundly affect how Swift developers program for years, so it needs to be done right.<div><br></div><div>See below:</div><div><br></div><div><b>Proposal</b></div><div><br></div><div><div>An existential type is defined using the &quot;Any&lt;...&gt;&quot; construct. Existential types can be nested.</div><div><br></div><div>The empty existential type &quot;Any&lt;&gt;&quot; is typealiased to &#39;Any&#39;.</div><div><br></div><div>Within the angle brackets are zero or more &#39;clauses&#39;. Clauses are separated by semicolons. (This is so commas can be used in where constraints, below. Better ideas are welcome. Maybe it&#39;s not necessary; we can use commas exclusively.)</div><div><br></div><div>There are five different possible clauses:</div><div><br></div><div><ul><li>&#39;class&#39;. Must be the first clause, if present. Places a constraint on the existential to be any class type. (Implies: Only one can exist. Mutually exclusive with class name clause.)<br></li></ul></div><div><br></div><div>(In the future a follow-up proposal should add in &#39;struct&#39; or &#39;value&#39; as a counterpart.)</div><div><br></div><div><ul><li>Class name. Must be the first clause, if present. (Implies: Only one can exist. Mutually exclusive with &#39;class&#39;.) Places a constraint on the existential (not really an existential anymore) to be an instance of the class, or one of its subclasses.<br></li></ul></div><div>Example: Any&lt;UIViewController; UITableViewDataSource; UITableViewDelegate&gt;</div><div>&quot;Any UIViewController or subclass which also satisfies the table view data source and delegate protocols&quot;</div><div><ul><li>Dynamic protocol. This is entirely composed of the name of a protocol which has no associated types or Self requirement.<br></li></ul></div><div><br></div><div>Example: Any&lt;CustomStringConvertible; BooleanType&gt;</div><div>&quot;Any type which conforms to both the CustomStringConvertible and BooleanType protocols&quot;</div><div><br></div><div>I&#39;m going to use &#39;static protocol&#39; to refer to a protocol with associated types or self requirements. Feel free to propose a more sound name.</div><div><br></div><div><ul><li>Self-contained static protocol, simple. This is composed of the name of a static protocol, optionally followed by a &#39;where&#39; clause in which the associated types can be constrained (with any of the three basic conformance types: subclassing, protocol conformance, or type equality). Associated types are referred to with a leading dot.<br></li></ul></div><div><br></div><div>Example: Any&lt;Collection where .Generator.Element : NSObject, .Generator.Element : SomeProtocol&gt;</div><div>&quot;Any type that is a Collection, whose elements are NSObjects or their subclasses conforming to SomeProtocol.&quot;</div><div><br></div><div><ul><li>Bound static protocol. This is the same as a self-contained static protocol, but with a leading &quot;&lt;name&gt; as &quot; which binds the protocol to a generic typealias. The name can be then be used in subsequent clauses to build constraints.<br></li></ul></div><div><br></div><div>Example: Any&lt;T as Collection; IntegerLiteralConvertible where .IntegerLiteralType == T.Element&gt;.</div><div>&quot;Any type that is a Collection, and also can be built from an integer literal, in which the collection elements are the same type as the type of the integer used for the integer literal conformance.&quot;</div><div><br></div><div>There will be rules to prevent recursive nesting. For example, if generic typealiases are allowed, they cannot refer to each other in a circular manner (like how structs can&#39;t contain themeselves, and you can&#39;t create a cyclic graph of enums containing themselves).</div><div><br></div><div>How an existential can be used depends on what guarantees are provided by the clauses. For example, &#39;Any&lt;Equatable&gt;&#39; can&#39;t be used for much; if there were any methods on Equatable that did not use the associated types at all you&#39;d be able to call them, but that&#39;s about it. However, &#39;Any&lt;Equatable where .Self == String&gt;&#39; would allow for == to be called on instances. (This is a stupid example, since Any&lt;Equatable where .Self == String&gt; is equivalent to &#39;String&#39;, but there are almost certainly useful examples one could come up with.)</div></div><div><br></div><div>In order of increasing &#39;power&#39;:</div><div><ul><li>Don&#39;t constrain any associated types. You can pass around Any&lt;Equatable&gt;s, but that&#39;s about it.</li><li>Constrain associated types to conform to protocols.</li><li>Fully constrain associated types.</li></ul></div><div><br></div><div><br></div></div></div>