SE-0235 - Add Result to the Standard Library

I disagree to add Result to the standard library for now.

Major use cases of Result are error handling of asynchronous operations. We will be able to do it without Result when Swift supports async/await.

// without `Result` nor `async/await`
func download(from url: URL, _ completion: (Data?, Error?) -> Void)

// with `Result`
func download(from url: URL, _ completion: Result<Data, Error> -> Void)

// with `async/await`
func download(from url: URL) async throws -> Data

Even when async/await is supported, I think we will still need Result to combine with Future for concurrent asynchronous operations if Future does not support error handling. However, I think Result by a simple implementation like below would be enough for those purposes.

enum Result<Value> {
    case success(Value), failure(Error)
    func get() throws -> Value { ... }
}

// assuming that parameterized extensions are supported
extension<T> Future where Value == Result<T> {
    init(_ body: () async throws -> Void) { ... }
}

// concurrent asynchronous operations
let futureData1: Future<Result<Data>> = .init { try await download(from: url1) }
let futureData2: Future<Result<Data>> = .init { try await download(from: url2) }

// instead of `get().get()`, single `get()` with `async throws` can be implemented
// for `Future<Result<_>>` in the extension above
let data1: Data = try await data1.get().get()
let data2: Data = try await data2.get().get()
foo(data1, data2)

I think what we want about Result becomes clear after we start using async/await and Future for Swift. In addition, we have not concluded if we need typed throws, which affect if we want the second type parameter of Result. Because Result is purely additive, we have no reason to add Result to the standard library now. So I think it is too early to discuss Result for the present.

10 Likes