SE-0295: Codable synthesis for enums with associated values (second review)

Enum cases with associated values aren't documented in LibraryEvolution.rst, or the Library Evolution in Swift blog post. But as far as I can tell, most changes aren't binary or source compatible:

  • adding a new associated value (regardless of its label, type, or default argument).
  • removing, reordering, or relabelling an existing associated value.

I think the only possible changes are:

  • adding, changing, or removing an internal parameter name.
  • adding (but not changing or removing) a default argument.

Therefore, a public enum case can't evolve, even if a keyed container is used for its associated values.


I also question the importance of compatibility with the Rust library. Surely, the ability to easily map to other existing encodings is more useful?

In the previous review thread, there was:


If we wanted a simple encoding (in JSON at least), and didn't care about compatibility, we could use unkeyed containers in all cases.

For example, the following cases:

let commands: [Command] = [
  .dumpToDisk,
  .load1st("MyKey"),
  .load2nd(key: "MyKey"),
  .store3rd("MyKey", value: 42),
  .store4th(key: "MyKey", value: 42)
]

would encode their case names and associated values (but without any other labels):

[
  ["dumpToDisk"],
  ["load1st", "MyKey"],
  ["load2nd", "MyKey"],
  ["store3rd", "MyKey", 42],
  ["store4th", "MyKey", 42]
]

Customization should be possible via CodingKeys, but not JSON conversion to/from snake-case. (I guess this is similar to RawValue == String enums.)

3 Likes