What is your evaluation of the proposal?
-1
Is the problem being addressed significant enough to warrant a change to Swift?
It depends which problem specifically is being addressed by Result
. Essentially all of the compelling cases I see involve asynchronous code. Error propagation in such code is certainly a really big problem, but I don't think this is necessarily the best solution. See below.
Does this proposal fit well with the feel and direction of Swift?
I don't think so. The idea of using a Result
type comes from the pattern of using completion-handler closures. That is, people are (rightly) dissatisfied with this:
performOperation(with: value, completion: { (result: Int?, error: Error?)->Void in
})
and want to write it more like this, to express that the result and error values are mutually exclusive:
performOperation(with: value, completion: { (result: Result<Int, Error>)->Void in
})
So the real question is whether we are happy sticking with the completion-handler pattern as our concurrency model. AFAIK, that model was inherited from Obj-C and its ultimate fate is still unresolved; I have heard plenty of good arguments for using an async/await
model instead. So the above code would become:
let result: Int = try await performOperation(with: value)
With no Result
type needed at all.
I entirely sympathise with people who are frustrated with the lack of a language-integrated concurrency model in Swift, and have turned to Result<T>
as a workaround. Likewise, I know the pain of having to constantly map to/fro between equivalent types from multiple libraries. The truth, though, is that baking this workaround in to the standard library and ABI is entirely premature.
I also consider this is a backdoor way to introduce typed throws
in the language, which I'm also against.
Additionally, as @soroush mentioned, I think it's obvious that people will want this type to gain special language support - from if let
syntax to implicit conversions between (A) throws -> B
and (A)->Result<B, Error>
, and maybe even from Result<T>
to Optional<T>
. I think this is a very slippery slope.
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
I can't directly compare it with anything I've used before, but in general I strongly dislike typed exceptions in languages such as Java. I find that it greatly increases coupling, with little/no benefit; Errors are almost never handled exhaustively.
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
Participated in this and previous discussions, including about typed-throws and the concurrency model in general.