On Sat, Apr 16, 2016 at 3:56 AM, Brent Royal-Gordon <br...@architechies.com> wrote:
> (I favor "Values" because "Value" in the singular implies to me that you > can take a single value and enumerate it somehow, which is not what I have > in mind.) > OK, after reading it this way long enough, I'm on board with that. Anyway, if this ever gets into review, it'll be subject to internal bikeshedding. > > > > ### Should allValues implementations be derived for Comparable enums? > What if the sorted order does/doesn't match the source order? > > > > 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'm in > agreement here: having the values be ordered is a good implementation of > the principle of least surprise.) > > With the impending introduction of a `Comparable` requirement on > collection indices, we now have a second good reason for this: the values > themselves are good candidates to index into the `allValues` collection, > and they will need to be `Comparable`. > > Incidentally, one open question is whether enums with raw values should be > compared in source order or in raw value order. In other words, in: > > enum Foo: ValuesEnumerable { > case bar = 2 > case baz = 1 > } > > Is `Foo.allValues` equivalent to `[bar, baz]` or `[baz, bar]`? I'm not > certain we can always reliably sort raw values at compile time; `String` is > particularly worrisome because sort order tends to depend on tables built > into the OS, but even integer literals are suspect when you consider that > this feature can be used to initialize *any* `IntegerLiteralConvertible` > type (or `StringLiteralConvertible`, or I believe `FloatLiteralConvertible` > as well). Analyzing a raw value's sort order eventually becomes equivalent > to analyzing a custom Comparable implementation. > Good questions. Although I said I liked the idea of having allValues be in Comparable order, I'm now leaning towards source order. It avoids extra burden on the derived implementation (or on the documentation of the protocol), and the user can get them in sorted() order easily if desired. (However, we need to consider effects on the library evolution/resilience support.) > > Suppose we introduce a `ValuesCountable` (or maybe just `Countable`) > protocol like this: > > protocol ValuesCountable: Strideable /* implies Comparable and > Equatable */ { > associatedtype Stride: SignedInteger > static var allValues: CountableClosedRange<Self> { get } > } > > Swift already synthesizes Equatable. We could additionally have it > synthesize: > > • A `<` which compares the bit pattern (or perhaps the raw > values?) to determine ordering. > • A `distance(to:)` and `advanced(by:)` which operate with > knowledge of the known-good values. > • An `allValues` which basically amounts to just `return <first > case>...<last case>`. > This is an interesting idea. It's nice to think that the whole thing could be built on the existing range/interval types, and I appreciate your thinking through it with consideration for upcoming features/changes. However, requiring (and/or synthesizing) a Comparable and Strideable implementation seems like it would be overkill for most use cases, and for some enums it may not be appropriate to require either one. I'd like to see these ideas (or this whole feature) revisited after the Swift 3 changes to collections/iterators and generics have settled down, but IMO this is beyond what we should be shooting for as an initial version. Jacob
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution