Adding Either type to the Standard Library

Anonymous sum types would be, by their nature, anonymous; therefore, adding an additional case would create a distinct type. This is a source-breaking (not to mention ABI-breaking) change unless you have some sort of subtyping relationship between one anonymous sum type and another (or an 'extensible' anonymous sum type, which would be equivalent for these purposes).

let argument: (action: Action | change: Change) = .action(action)

event.handle(argument)
// error: cannot convert value of type
//   '(action: Action | change: Change)'
//   to expected expected argument type
//   '(action: Action | change: Change | sideEffect: SideEffect)'

For reasons I outline above, your example above regarding API stability is not possible unless there's some sort of subtyping relationship that's supported, which there cannot be in Swift.


It's very much true that the ergonomics of working with cases with payloads never been ideal. One needs only to try implementing a JSON type using an indirect enum; it's an exercise that descends quickly to absurdity if you're not careful, and the user of such an API wouldn't have a good time at all.

To be sure, it's more straightforward to create a case with a payload than to extract it, and there are a large number of conveniences that the core team has pointed out should be considered which deal primarily with working with an existing value. However, what's wrapped has to be unwrapped, so ergonomic issues with payloads are all of a kind.


It is more an empiric question, whether a feature promotes or detracts from the overall goal to steer users towards the best solution. This is why I worked through the examples you provided. If there is a "killer use case" for the feature, then it should be possible to discover it. That we have seen many examples that are worse off using this feature, and none seem to fit the description of a "killer use case," raises concerns.

It isn't enough just to have lots of examples where a feature could be used; a successful proposal should have examples (preferably many, and preferably obvious) where the feature could be well used.


I didn't cherry pick; I'm working through your examples in reverse order (since the last examples were the freshest on my mind).

As to your new example: another way to express the result would be var isConsentApproved: Bool?. In general, nil is a good way to model the lack of a value.

Yes, it is important to consider that you may have use cases with more than two or even three cases. In the case of tuples, though, we've discovered that the maximum ergonomic number of elements is fairly low, past which one is better off creating a real struct. Is it possible to come up with a situation where four or five cases are more ergonomic as an anonymous sum type rather than a named enum? Possibly, but it starts to become quite iffy, if we use our experience with tuples as a guide.


Whether we accept or reject this feature has to be contingent also on whether we can come up with a workable solution to these very practical issues.

It's related to the point I made earlier about looking at examples as a key part of evaluating a proposal; we shouldn't be making a decision on including a feature based on abstract considerations, then trying to figure out if we can.

As I said earlier in this thread, I would want implicit conversions if we had anonymous sum types. This is also not the first thread about this issue, and many people have wanted the same; it's "commonly proposed" for a reason.

2 Likes