Hello, Swift Community.
The review for the revisions to SE-0235: Add
Result to the Standard Library ran from November 28th through December 2nd. You can find the review thread here. There was also an earlier round of review for the initial proposal.
The community provided a lot of very good feedback on the proposed revisions. Almost all of it was strongly positive about the revised proposal overall, but many community members expressed reservations about various aspects of it. The Core Team discussed this feedback today and reached several conclusions:
While several members of the community supported naming the cases
error, overall people seemed to prefer the original proposal's case names:
failure. After considering this feedback, the Core Team has come to agree that these are excellent "semantic" names which work better than
erroras labels for the current state of a
Resultvalue. They read more fluently when constructing a
Resultor pattern-matching on it, especially when the value type is
(), and they avoid confusion over the fact that a
Resultis itself a value.
The concern that originally led the Core Team to suggest renaming the cases was about the cognitive load of using different names for the cases, case accessors, and type parameters of the same type. It's easy to remember these differences when reading the proposal, but this will predictably become an annoyance after a few months. But this doesn't specifically require using
error; any consistent set of names will do. So we should consider whether we could use
failurefor the type parameters and case accessors.
Failureare reasonable choices for the type parameter names.
Failureis particularly nice because it's a problem to have both an
Errorparameter and a global
Swift.Errortype: not because the shadowing is difficult for the compiler, but because the reuse of the name makes code harder to read and — perhaps more importantly — makes it unnecessarily awkward to talk about in person. These names are also rarely used in code, as they only ever need to be written within extensions of
Case accessors are a more complex question. The current proposal doesn't include case accessors, but the original proposal did, and we're anticipating a future proposal that will add automatic synthesis for case accessors. That synthesis will undoubtedly use names based on the actual case names, so at a first glance, it seems imprudent to use case names that we're not sure we'd want for the accessors. However, feedback on this review has led the Core Team to more seriously consider this issue, and it now seems quite complicated. A name that's a good name for a particular state of an
failure) might not be a good name for a value carried in that case (like
error). It may be true that case accessor names will always end up feeling a little contrived, and so it's just better to use the actual case names because they're easy to interpret. More importantly, we don't want to burden this proposal because we haven't resolved those questions yet to our satisfaction.
Accordingly, the case names are revised (back) to
failure, and the type parameter names are revised to
Many people in the community strongly supported requiring
Failureto conform to
Error, although this was not universal. The Core Team remains convinced that this is the right thing to do. We do not see any need to add new conformances to
Errorfor library types like
Several members of the community voiced disappointment that the proposal did not include a variant of
flatMapthat took a throwing closure. The Core Team reaffirms its desire to never overload methods by whether an argument function can throw. We spent quite some time debating whether a different name would be acceptable, such as
flatMapThrowing, but were unable to reach consensus on this, especially as there are alternative means of expressing this using the catching initializer.
Several members of the Core Team expressed discomfort with the use of the name
flatMapon non-collection types. Since it would be unreasonable for the Core Team to introduce a novel name without review, and since there is already precedent for this name from
Optional.flatMap, and since this is quite an important operation on
Result, there was consensus to accept it under the name
flatMapregardless of that discomfort. However, we would like to invite further discussion about the name of this operation on
Accordingly, the map functions remain as stated in the revision.
Several members of the community expressed dislike of the name
unwrapped(), as it seems insufficiently "active" for an operation that is essentially designed to throw as a core part of its operation. The Core Team agrees and also feels that
unwrappedis awkward because nothing else about
Resultuses "wrapping" as an analogy. Furthermore, a similar operation will be needed on other computation-related types like
Future, and it would be good for these to share a consistent name. The Core Team debated this and ultimately settled on
get(). That this operation can throw should be apparent enough from the mandatory use of
trybefore the call.
The Core Team acknowledges the call from several reviewers to make a special effort to communicate how we think
Result ought to be used in Swift. We absolutely agree that is an important part of adding
Result to the language, and we intend to provide this guidance as part of the release.
Although we are revising the proposal again, the Core Team feels that these issues have already received adequate review, and there is no need for a third round of review. Accordingly, SE-0235 has been Accepted with Modifications.
Please remember that there will be opportunities to extend this type in the future.
As always, thank you for helping to make Swift a better language.