SE-0266 — Synthesized Comparable conformance for enum types

+0.95 in its current form, +1 with support for raw value enums (compared using declaration order).

SE-0266 is proposing that, for enums without raw/associated values or with all Comparable associated values, declaring conformance to Comparable without an explicit implementation of < is a declaration of intent by the user that they want a declaration-order-based ordering. Doing the same for enums with raw values is wholly consistent with that.

The compiler implementation also leads to a potentially odd inconsistency. From what I can tell, this enum would not receive synthesized Comparable:

enum Foo: Int, Comparable {  // ERROR
  case bar = 1
  case baz = 2
}

but writing it this way, which is semantically equivalent, would receive synthesis:

enum Foo: RawRepresentable, Comparable {  // OK
  case bar
  case baz

  init?(rawValue: Int) {
    switch rawValue {
    case 1: self = .bar
    case 2: self = .baz
    default: return nil
    }
  }

  var rawValue: Int {
    switch self {
    case .bar: return 1
    case .baz: return 2
    }
  }
}

So under the current proposal, I would be able to have RawRepresentable synthesis or Comparable synthesis, but not both at the same time. More importantly, if the argument against supporting enums with raw values is about potential confusion about what should be compared, then shouldn't that argument also apply to the second form above?

As @Nevin points out, implementing Comparable.< based on rawValue is easy if that's the behavior you want. Implementing it based on declaration order is extremely difficult or laborious, or this proposal wouldn't exist. So let's just go all the way here; synthesizing it for raw value enums and asking the user to write a one-liner to use a different implementation is IMO a better choice than requiring authors of raw value enums who want declaration-order comparison to implement it as though this proposal didn't exist.

24 Likes