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

On the contrary, enabling users to use the language of their own choosing when it comes to variables has been a part of Swift from the get-go. It is absolutely not a goal to favor English speakers when it comes to type names.

7 Likes

I don't know what you mean by restricting other languages, or rules. We may agree more than I first suspected. But certainly the API naming convention of using prepositions as argument labels, and verbs as function names, combined with the strict Swift syntax where argument labels prepend the argument, effectively disgourages use of other languages that has different word order typology than English.

But I digress.

My understanding of "prepositions as argument labels, and verbs as function names" is that they're simply the result of argument labels conveying relations and functions being actions. These language features are universal, if one accepts that there is a universal grammar.

I don't think word order is relevant, since Swift code rarely forms grammatically correct English sentences. Also, here is a counter example: English's word order is subject-verb-object, and French subject-object-verb, but it doesn't stop me from writing functions like this:

func entrer(dans laPorte: BarriĆØre) { ... }

which should be equivalent to

func enter(through door: Barrier) { ... }

This is very clever! One issue I have is that this approach may have a significant binary cost. I'm not 100% clear on how marker protocols work, but I don't think the protocols you propose can't be marker protocols like Sendable (because you can't is a marker protocol). While enums-with-associated-types aren't as prevalent as Sendable types, they are still a major source of binary bloat, especially in codebases where automatic synthesis would be most useful (this was very much the case at Airbnb).

1 Like

Thanks! :blush: I know itā€™s not a marker protocol in the sense that Sendable Is - I just used the word as ā€˜a protocol with no requirementsā€™. :blush:
And youā€™re right - this will have some cost, although I donā€™t think will mean much for many users.
But of course no cost is better than any cost so your solution is better in that regard - and also cleaner and a better fit over all.

I thought a bit about it and the conformance could be made to the synthesized CodingKeys of this proposal entirely in ā€˜user codeā€™ - so I can start using this with little manual labor if/once this feature lands. I know itā€™s not for everyone, but I think it will overall clean up our code base at work.

1 Like

Can you elaborate on this? I don't think there is a way to extend the synthesized coding keys (they are synthesized as private so statements like extension Foo.CodingKeys won't work), and you would still have to write your own custom encoder.

I've thought about this a bit more, and I'd like to amend my response to a +0.5.

The main thing that changed for me is that I now believe we can add the functionality I discussed incrementally. In broad strokes:

  1. Add automatic synthesis to enums with associated types (this proposal)
  2. Add new container types and a default implementation which matches the proposed semantics by calling back into the current set of container types. (I think this will work, but maybe someone can think of a counterargument?)
  3. Add strategies onto JSONDecoder for enum-with-single-associated-type and friends that enable more intuitive serialization styles.

The downside here is that the default would be a little clumsy with its fondness for underscored ordinals, but that isn't a dealbreaker for me especially since this effort historically had some trouble making it through the evolution process. That said, I would still prefer this proposal be amended to special-case the single-unlabeled-associated-type case as this would greatly increase the utility of this new functionality.