So, an update! This came up while I was talking to members of the core team, 
and ChrisL felt very strongly that restricting reordering of enum elements was 
a no-go, since it would be the only part of the language that worked this way 
(even if it only mattered for binary frameworks). Ted also rightly pointed out 
that any such language-level restriction would have to be reviewed by the core 
team.

So where does that leave us?

- The naive implementation is to turn a switch into an if-else chain, 
unfortunately requiring one function call per case to match.

- A slightly more complex solution keeps a single 'getMyOpaqueEnumTag' entry 
point (see original email), but exposes symbols for every tag. The values of 
the symbols would be kept in alphabetical order, which allows the generated 
code to do a binary search over the cases they care about. This still means N 
symbols, but a switch that involves several of them doesn't necessarily have to 
take linear time.

- Joe Groff came up with this idea that also involves sorted symbols:

switch indexForMyOpaqueEnumTag(&myOpaqueEnum, [MyOpaqueEnum.intCase, 
MyOpaqueEnum.stringCase]) {
case 0:
  var payload: Int
  getMyOpaqueEnumPayload(&myOpaqueEnum, MyOpaqueEnum.intCase, &payload)
  doSomething(payload)
case 1:
  var payload: String
  getMyOpaqueEnumPayload(&myOpaqueEnum, MyOpaqueEnum.stringCase, &payload)
  doSomethingElse(payload)
default:
  print("unknown case")
}

In this example, the actual tag values for 'intCase' and 'stringCase' might not 
be 0 and 1, but 'indexForMyOpaqueEnumTag' can do the binary search to find out 
which enum we're asking for. Like the previous solution, you only have to check 
the cases you care about, but this time the binary search is in the callee, 
rather than the client.

- Use availability ordering, plus some kind of explicit annotation for when 
multiple cases are added within the same release. (In this thread people have 
suggested dates, ad-hoc sub-version numbers, and plain integer values.)

I appreciate everyone's creativity with solving the availability ordering 
problem, but I don't want to tie us to a checker that will tell you if you 
screw up or a history scraper that will implicitly add the right annotations. 
(I don't think those are bad ideas, but they're a whole extra pile of work on 
top of the main implementation!) That leaves explicit annotations of some kind, 
and that leaves us in a worse place than Objective-C. Which is permitted, but 
not desirable.

 At this point in time I think the second option is the best one we have: it's 
relatively simple to implement, it supports everything Objective-C does, and it 
doesn't make the availability model even more complicated. It is going to be 
less efficient than actually knowing the case numbers at compile time, though. 
Still, as Slava's pointed out, we can still change this after we go ABI-stable; 
doing something more efficient will just be limited based on deployment target.

Jordan

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to