<div dir="ltr">...1 month passes...<div class="gmail_extra">
<br><div class="gmail_quote">On Mon, Apr 25, 2016 at 8:31 AM, Vladimir.S via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Sorry, if was discussed earlier, tried to find in conversations in this thread but didn&#39;t find:<br>
<br>
Could someone please briefly describe why &quot;community is in agreement&quot; - &quot;The &quot;allValues&quot; behavior should be provided by conformance to some protocol&quot; ?<br>
I mean, what is purpose of the protocol? What else, other than allValues for enums, could be implemented with such protocol? How it will be used?(Like to see a possible code sample)<br></blockquote><div><br></div><div>Whether the `allValues` property should be exposed as a protocol requirement was one of the main questions I brought up at the beginning of this thread.</div><div><br></div><div>Personally, I&#39;m fine with ValuesEnumerable being a &quot;magic protocol&quot; like ErrorProtocol, because the most important use case is being able to write e.g. `NSTextAlignment.allValues` with a compiler-provided implementation. A proper associatedtype declaration can come later, once generics are mature enough.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">How I think about this feature: we have &quot;simple&quot; enums(.First, .Second, .Third), we have enums with &quot;raw&quot; values(.First = 1) and we have &quot;complex&quot; enums like<br>
enum E&lt;T&gt; {<br>
    case First(Int,T)<br>
    case Second(SomeStruct)<br>
}<br>
<br>
What we need? We need to be able to iterate over all declared cases in enum. Often we needs to pre-create some resources depending on what &#39;kind&#39; of values(and their count) could be in enum.<br>
<br>
Let&#39;s take this &quot;complex&quot; E&lt;T&gt; enum.<br>
IMO we need to be able to have such code:<br>
<br>
let columns = Columns(count: E&lt;Int&gt;.allValues.count)<br>
<br>
for e in E&lt;Int&gt;.allValues {<br>
  switch e { // &lt;&lt; here is a problem for complex enums, it can&#39;t return actial enum value as assotiated values are not known (Int,T)/SomeStruct<br>
// but there is no problem for &quot;simple&quot; enums to return actual value here<br>
<br>
    case .First : columns.newColumn(titled: &quot;First&quot;, color: red)<br>
    case .Second : columns.newColumn(titled: &quot;Second&quot;, color: blue)<br>
<br>
    // !!! no &#39;default:&#39; here : this will protect us if E is changed<br>
  }<br>
}<br>
<br>
As I understand, to be able to iterate &#39;complex&#39; enums we need some new type related to enum. I mean what exactly are &quot;.First&quot; and &quot;.Second&quot; that are specified inside &#39;switch&#39;? I.e. what is placed by compiler inside &#39;switch&#39; as &quot;.First&quot; and as &quot;.Second&quot;? What hidden property of e is compared with these &quot;.First&quot; and &quot;.Second&quot; ?<br>
<br>
Here is the code:<br>
<br>
var e : E&lt;String&gt; = .First(1, &quot;str&quot;)<br>
switch e { // e is compared in run-time<br>
    case .First : print(&quot;first&quot;)   // e is a concrete value of &#39;complex&#39; enum, but we can compare just &#39;.First&#39; about it. So, .First does not create an instance of E&lt;String&gt;, it is some &#39;special&#39; value<br>
<br>
    case .Second : print(&quot;second&quot;)<br>
}<br>
<br>
It seems like we need some &#39;magic&#39; EnumCase type and some compiler changes to be able to write some kind of this:<br>
<br>
for e in E&lt;Int&gt;.allCases { // e is EnumCase, we have need .allCases<br>
  switch e {<br>
<br>
// here compiler allows to use our EnumCase to get a general &#39;kind&#39; of<br>
defined cases in enum<br>
// i.e. &#39;e&#39; contains the same value(and only this value) that compiler internally stores in &#39;switch&#39; now (in code above)<br>
<br>
    case .First : columns.newColumn(titled: &quot;First&quot;, color: red)<br>
    case .Second : columns.newColumn(titled: &quot;Second&quot;, color: blue)<br>
<br>
    // !!! no &#39;default&#39; here, it is important!<br>
    // because of this we need compiler magic insted of checking some<br>
    // function like E&lt;Int&gt;.caseIf(from: .First) as function will require<br>
    // a &#39;default:&#39; clause.<br>
  }<br>
}<br>
<br>
As for &#39;simple&#39; enums - they can be iterated without such special &#39;EnumCase&#39; type, but for consistency probably could be implemented in the same way. Or for &#39;complex&#39; enums we need such a special case.<br>
<br>
As for ordering, it is clear for me that we need order items in allValues exactly as defined in code. We always can have rawValue from enum, but can&#39;t get enum definition order by rawValue.<br>
<br>
Opinions?<br>
Please let me know if something is incorrect in my reasoning</blockquote><div><br></div><div>Your reasoning is correct. This proposal was only intended to handle the &quot;simple&quot; case, because having a good solution for the simple case sooner, rather than waiting for a <b>perfect</b> solution much later, seems like a good idea to me.</div><div><br></div><div><br></div><div>To me, it seems that a &quot;magic protocol&quot; with no public requirements, producing an internal (non-resilient) static array, is a reasonable solution that <b>might</b> be able to fit into the Swift 3 timeframe, and I think that&#39;d be a huge boon to language users. I also don&#39;t think it precludes further improvements.</div><div><br></div><div>Do others agree? Disagree? Is it definitely out of scope for Swift 3 regardless of the approach we choose?</div></div></div></div>