Sorry, if was discussed earlier, tried to find in conversations in this thread but didn't find:

Could someone please briefly describe why "community is in agreement" - "The "allValues" behavior should be provided by conformance to some protocol" ? 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)

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
enum E<T> {
    case First(Int,T)
    case Second(SomeStruct)
}

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.

Let's take this "complex" E<T> enum.
IMO we need to be able to have such code:

let columns = Columns(count: E<Int>.allValues.count)

for e in E<Int>.allValues {
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
// but there is no problem for "simple" enums to return actual value here

    case .First : columns.newColumn(titled: "First", color: red)
    case .Second : columns.newColumn(titled: "Second", color: blue)

    // !!! no 'default:' here : this will protect us if E is changed
  }
}

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" ?

Here is the code:

var e : E<String> = .First(1, "str")
switch e { // e is compared in run-time
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

    case .Second : print("second")
}

It seems like we need some 'magic' EnumCase type and some compiler changes to be able to write some kind of this:

for e in E<Int>.allCases { // e is EnumCase, we have need .allCases
  switch e {

// here compiler allows to use our EnumCase to get a general 'kind' of
defined cases in enum
// i.e. 'e' contains the same value(and only this value) that compiler internally stores in 'switch' now (in code above)

    case .First : columns.newColumn(titled: "First", color: red)
    case .Second : columns.newColumn(titled: "Second", color: blue)

    // !!! no 'default' here, it is important!
    // because of this we need compiler magic insted of checking some
    // function like E<Int>.caseIf(from: .First) as function will require
    // a 'default:' clause.
  }
}

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.

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.

Opinions?
Please let me know if something is incorrect in my reasoning
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to