<div dir="ltr"><div>This discussion is about a proposal for API to enumerate/count all possible values of a type, particularly enums. The goal is to address potential issues with an old proposal, so it can go up for review soon.</div><div><br></div><div>Core Team / Standard Library Team feedback would be particularly welcome here, because we want this feature to mesh well with the goals &amp; future directions that are already in mind for Swift. If any details the core team would like to see are missing from the proposal, please let us know now.</div><div><br></div><div>Background reading:</div><div><br></div><div>    • 2015-12-08: &quot;List of all Enum values (for simple enums)&quot; — <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/10064" target="_blank">http://thread.gmane.org/gmane.comp.lang.swift.evolution/10064</a></div><div>    • 2015-12-21: &quot;Proposal: Enum &#39;count&#39; functionality&quot; <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/644" target="_blank">http://thread.gmane.org/gmane.comp.lang.swift.evolution/644</a></div><div>    • 2016-01-17: &quot;Draft Proposal: count property for enum types&quot; <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/3678" target="_blank">http://thread.gmane.org/gmane.comp.lang.swift.evolution/3678</a></div><div>    • 2016-01-18: &quot;Pre-proposal: CaseEnumerable protocol (derived<span style="white-space:pre-wrap"> </span>collection of enum cases)&quot; at <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/3701" target="_blank">http://thread.gmane.org/gmane.comp.lang.swift.evolution/3701</a></div><div>    • 2016-01-20: My subsequent proposal PR #114: <a href="https://github.com/apple/swift-evolution/pull/114" target="_blank">https://github.com/apple/swift-evolution/pull/114</a></div><div><br></div><div>A lot has happened since then:</div><div><br></div><div>    • 2016-03-03: &quot;[Manifesto] Completing Generics&quot; <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/8484" target="_blank">http://thread.gmane.org/gmane.comp.lang.swift.evolution/8484</a></div><div>    • 2016-03-03: &quot;[Accepted with modifications] SE-0023 API Design<span style="white-space:pre-wrap"> </span>Guidelines&quot; <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/8585" target="_blank">http://thread.gmane.org/gmane.comp.lang.swift.evolution/8585</a> &amp; <a href="http://apple.github.io/swift-internals/api-design-guidelines/" target="_blank">http://apple.github.io/swift-internals/api-design-guidelines/</a></div><div>    • 2016-03-09: Brent&#39;s proposal PR #199: <a href="https://github.com/apple/swift-evolution/pull/199" target="_blank">https://github.com/apple/swift-evolution/pull/199</a></div><div><br></div><div>Brent brought up some great points in his proposal, but ultimately closed the PR in anticipation of further discussion. I&#39;m sorry I haven&#39;t had much time to put into this until now, but I&#39;d like us to get the discussion going again.</div><div><br></div><div>I believe the community is in agreement about the following:</div><div><br></div><div>    • The &quot;allValues&quot; behavior should be provided by conformance to some protocol, named ValueEnumerable or ValuesEnumerable or similar.</div><div>    • The compiler should derive an allValues implementation for &quot;simple&quot; enums (those without associated values).</div><div><br></div><div>There are a couple things which we must still decide:</div><div><br></div><div><b>### Should the ValueEnumerable protocol expose the allValues property, or should it be an empty protocol like ErrorType (ErrorProtocol)? If exposed, what is its type?</b></div><div><br></div><div>If allValues were exposed as part of the protocol, then the generic constraint &lt;T: ValueEnumerable&gt; could be used meaningfully, i.e. you could write/use &quot;T.allValues&quot;.<br></div><div><br></div><div>On the other hand, the limitations of the current generics system don&#39;t allow &quot;<b>associatedtype ValueCollection: Collection where ValueCollection.Iterator.Element == Self</b>&quot;. Doug&#39;s <i>Completing Generics</i> manifesto included &quot;<i>Arbitrary requirements in protocols</i>&quot;, under the category of &quot;Minor extensions&quot;, which would remove this limitation. If this gets implemented, I think it makes a lot of sense to use it here.</div><div><br></div><div>Until then, though, we&#39;d have to pick a concrete type for the collection. Brent proposed that it be an Array, &quot;static var allValues: [Self]&quot;.</div><div><br></div><div>The biggest reason I didn&#39;t expose allValues on the protocol was that I figured we&#39;d want to allow for efficient implementations which wouldn&#39;t require allocating storage for *all* the values (just the endpoints, for instance), but could still count and iterate over them.</div><div><br></div><div>Another question on the subject of exposing the property as a protocol requirement: What should the diagnostics look like if it&#39;s missing? Maybe something like this:</div><div><br></div><div></div><div><font face="monospace, monospace">    struct MyType: ValueEnumerable { }</font></div><div><font face="monospace, monospace">    // error: type &#39;MyType&#39; does not conform to protocol &#39;ValueEnumerable&#39;</font></div><div><font face="monospace, monospace">    // note: protocol requires property &#39;allValues&#39; with type &#39;[MyType]&#39;</font></div><div><font face="monospace, monospace">    // <b>note: implementation of allValues cannot be automatically derived for a non-enum type</b></font></div><div><br></div><div><b>### Should allValues implementations be derived for Comparable enums? What if the sorted order does/doesn&#39;t match the source order?</b></div><div><br></div><div>Brent has suggested the semantics of allValues should be such that for Comparable types, allValues is guaranteed to be ordered. If that were the case, we might not want to require the compiler to derive a ValueEnumerable implementation, since the source order may not match the Comparable-sorted order, and verifying this could overly complicate things. (I think I&#39;m in agreement here: having the values be ordered is a good implementation of the principle of least surprise.)</div><div><br></div><div><br></div><div>Thoughts welcome.</div><br clear="all"><div><div><div dir="ltr"><div>Jacob<br></div></div></div></div>
</div>