<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"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></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't find:<br>
<br>
Could someone please briefly describe why "community is in agreement" - "The "allValues" behavior should be provided by conformance to some protocol" ?<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'm fine with ValuesEnumerable being a "magic protocol" 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 "simple" enums(.First, .Second, .Third), we have enums with "raw" values(.First = 1) and we have "complex" enums like<br>
enum E<T> {<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 'kind' of values(and their count) could be in enum.<br>
<br>
Let's take this "complex" E<T> enum.<br>
IMO we need to be able to have such code:<br>
<br>
let columns = Columns(count: E<Int>.allValues.count)<br>
<br>
for e in E<Int>.allValues {<br>
switch e { // << here is a problem for complex enums, it can't return actial enum value as assotiated values are not known (Int,T)/SomeStruct<br>
// but there is no problem for "simple" enums to return actual value here<br>
<br>
case .First : columns.newColumn(titled: "First", color: red)<br>
case .Second : columns.newColumn(titled: "Second", color: blue)<br>
<br>
// !!! no 'default:' here : this will protect us if E is changed<br>
}<br>
}<br>
<br>
As I understand, to be able to iterate 'complex' enums we need some new type related to enum. I mean what exactly are ".First" and ".Second" that are specified inside 'switch'? I.e. what is placed by compiler inside 'switch' as ".First" and as ".Second"? What hidden property of e is compared with these ".First" and ".Second" ?<br>
<br>
Here is the code:<br>
<br>
var e : E<String> = .First(1, "str")<br>
switch e { // e is compared in run-time<br>
case .First : print("first") // e is a concrete value of 'complex' enum, but we can compare just '.First' about it. So, .First does not create an instance of E<String>, it is some 'special' value<br>
<br>
case .Second : print("second")<br>
}<br>
<br>
It seems like we need some 'magic' EnumCase type and some compiler changes to be able to write some kind of this:<br>
<br>
for e in E<Int>.allCases { // e is EnumCase, we have need .allCases<br>
switch e {<br>
<br>
// here compiler allows to use our EnumCase to get a general 'kind' of<br>
defined cases in enum<br>
// i.e. 'e' contains the same value(and only this value) that compiler internally stores in 'switch' now (in code above)<br>
<br>
case .First : columns.newColumn(titled: "First", color: red)<br>
case .Second : columns.newColumn(titled: "Second", color: blue)<br>
<br>
// !!! no 'default' here, it is important!<br>
// because of this we need compiler magic insted of checking some<br>
// function like E<Int>.caseIf(from: .First) as function will require<br>
// a 'default:' clause.<br>
}<br>
}<br>
<br>
As for 'simple' enums - they can be iterated without such special 'EnumCase' type, but for consistency probably could be implemented in the same way. Or for 'complex' 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'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 "simple" 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 "magic protocol" 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'd be a huge boon to language users. I also don'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>