# SE-0235 - Add Result to the Standard Library

**URL:** <https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752>\
**Category:** Proposal Reviews\
**Created:** [November 7, 2018, 10:32pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752 "2018-11-07T22:32:55Z")\
**Posts on this page:** 20\
**Page:** 7

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [November 9, 2018, 3:10pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/122 "2018-11-09T15:10:21Z")

</div>

> [@Matt\_Gallagher](#):
>
> I'm far more worried about negative impacts this proposal might have on runtime performance if 2 generic parameters must be resolved during Swift type metadata lookup. All I can request is that Swift devs perform tests and offer assurances that `Result<Value, Error>` will be equivalent performance to `Result<Value>` if the `Error` type is hard-coded to be `Swift.Error` – including in cases where the `Value` is unspecialized and not known at compile time.

I haven’t done specific testing, but I would expect that the fixed costs of instantiating metadata far outweigh any per-generic-parameter cost. Once metadata is instantiated, it’s cached, and looking up a two-pointer key in a hash table isn’t all that much more expensive than a single-pointer key. The runtime has specialized code paths for 1...4 generic parameter metadata caches as well.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [November 9, 2018, 3:20pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/123 "2018-11-09T15:20:56Z")

</div>

> [@DevAndArtist](#):
>
> After that little mind experiment I don't think this methods can be called `flatMap` because they're not flattening the result of the closure. The behavior feels like a `compactMap` indeed.

The throwing signature for the transform is effectively just different syntax for a transform that returns `Result<NewValue, Error>`. That is why this method has `flatMap` semantics. `compactMap` is a filtering map. I don't see any filtering happening here. 😉

I find your proposed `map` and `flatMap` signatures are troublesome. As I have said many times before, I don't think we should have multiple error pathways in the same operation. If it returns `Result` it should not throw.

---

<div class="post-metadata">

**Author:** ![Brad\_Hilton](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/brad_hilton/32/5169_2.png) [@Brad\_Hilton](https://forums.swift.org/u/Brad_Hilton)\
**Post date:** [November 9, 2018, 3:56pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/124 "2018-11-09T15:56:03Z")

</div>

-1.

I think adding a Result type to the standard library could be nice, but in it's proposed form I'm going to have to vote no. The proposed `Result<Value, Error>` is marked departure from the current error-handling system which uses the `Error` protocol as first-class citizen. I think it would be a huge mistake to bifurcate Swift with two orthogonal error handling mechanisms.

I think the following amendments would make much more sense and be much easier for Swift developers to use today:

```swift
/// A value that represents either a success or failure, capturing associated
/// values in both cases.
@_frozen
- public enum Result<Value, Error> {
+ public enum Result<Value> {
  /// A success, storing a `Value`.
  case success(Value)
  
  /// A failure, storing an `Error`.
  case failure(Error)
  
  /// The stored value of a successful `Result`. `nil` if the `Result` was a
  /// failure.
  public var value: Value? { get }
  
  /// The stored value of a failure `Result`. `nil` if the `Result` was a
  /// success.
  public var error: Error? { get }
  
  /// A Boolean value indicating whether the `Result` as a success.
  public var isSuccess: Bool { get }
  
  /// Evaluates the given transform closure when this `Result` instance is
  /// `.success`, passing the value as a parameter.
  ///
  /// Use the `map` method with a closure that returns a non-`Result` value.
  ///
  /// - Parameter transform: A closure that takes the successful value of the
  /// instance.
  /// - Returns: A new `Result` instance with the result of the transform, if
  /// it was applied.
  public func map<NewValue>(
- _ transform: (Value) -> NewValue
- ) -> Result<NewValue, Error>
// closures that throw should be automatically create new results with thrown errors
+ _ transform: (Value) throws -> NewValue
+ ) -> Result<NewValue>
  
  /// Evaluates the given transform closure when this `Result` instance is
  /// `.failure`, passing the error as a parameter.
  ///
  /// Use the `mapError` method with a closure that returns a non-`Result`
  /// value.
  ///
  /// - Parameter transform: A closure that takes the failure value of the
  /// instance.
  /// - Returns: A new `Result` instance with the result of the transform, if
  /// it was applied.
- public func mapError<NewError>(
- _ transform: (Error) -> NewError
- ) -> Result<Value, NewError>
// This would be vastly simplified, simply take an error and return a new error if you so choose
+ public func mapError(
+ _ transform: (Error) throws -> Error
+ ) -> Result<Value>
  
  /// Evaluates the given transform closure when this `Result` instance is
  /// `.success`, passing the value as a parameter and flattening the result.
  ///
  /// - Parameter transform: A closure that takes the successful value of the
  /// instance.
  /// - Returns: A new `Result` instance, either from the transform or from
  /// the previous error value.
  public func flatMap<NewValue>(
- _ transform: (Value) -> Result<NewValue, Error>
- ) -> Result<NewValue, Error>
// Again throwing would be permitted integrating nicely with our existing system
+ _ transform: (Value) throws -> Result<NewValue>
+ ) -> Result<NewValue>
  
  /// Evaluates the given transform closure when this `Result` instance is
  /// `.failure`, passing the error as a parameter and flattening the result.
  ///
  /// - Parameter transform: A closure that takes the error value of the
  /// instance.
  /// - Returns: A new `Result` instance, either from the transform or from
  /// the previous success value.
- public func flatMapError<NewError>(
- _ transform: (Error) -> Result<Value, NewError>
- ) -> Result<Value, NewError>
// Again a vastly simplified signature with handling of existing niceties
+ public func flatMapError(
+ _ transform: (Error) throws -> Result<Value>
+ ) -> Result<Value>
  
  /// Evaluates the given transform closures to create a single output value.
  ///
  /// - Parameters:
  /// - onSuccess: A closure that transforms the success value.
  /// - onFailure: A closure that transforms the error value.
  /// - Returns: A single `Output` value.
  public func fold<Output>(
    onSuccess: (Value) -> Output,
    onFailure: (Error) -> Output
  ) -> Output
}

- extension Result where Error: Swift.Error {
// Simplifies these extensions
+ extension Result {
  /// Unwraps the `Result` into a throwing expression.
  ///
  /// - Returns: The success value, if the instance is a success.
  /// - Throws: The error value, if the instance is a failure.
  public func unwrapped() throws -> Value
}

- extension Result where Error == Swift.Error {
+ extension Result {
  /// Create an instance by capturing the output of a throwing closure.
  ///
  /// - Parameter throwing: A throwing closure to evaluate.
  @_transparent
  public init(_ throwing: () throws -> Value)
  
 - /// Unwraps the `Result` into a throwing expression.
 - ///
 - /// - Returns: The success value, if the instance is a success.
 - /// - Throws: The error value, if the instance is a failure.
 - public func unwrapped() throws -> Value
  
- /// Evaluates the given transform closure when this `Result` instance is
- /// `.success`, passing the value as a parameter and flattening the result.
- ///
- /// - Parameter transform: A closure that takes the successful value of the
- /// instance.
- /// - Returns: A new `Result` instance, either from the transform or from
- /// the previous error value.
- public func flatMap<NewValue>(
- _ transform: (Value) throws -> NewValue
- ) -> Result<NewValue, Error>
}

extension Result : Equatable where Value : Equatable, Error : Equatable { }

extension Result : Hashable where Value : Hashable, Error : Hashable { }

extension Result : CustomDebugStringConvertible { }

```

What changes would need to be made to Swift to have an `Error` generic parameter make sense? There are a few things that could help:

1. Default generic types  
If you can declare `Result<Value, Error = Swift.Error>` that would dramatically reduce the boilerplate for what will be, by far, the most common use case.

2. Add typed throws  
Now a `Result` specific `Error` type makes total sense. Without typed throws it would be a strong divergence from error handling in modern Swift.

3. Add union types  
The biggest pain in practice with typed errors would be how unwieldy type composition is. To compose errors that bubble up would require defining `enum`s and wrapper types everywhere. If you could simply declare that a function `throws MyError | BespokeLibraryError` then the usability cost of typed errors is dramatically reduced.  
EDIT: Which I should note will not happen, proposals for union types have been rejected. This is a reason to be skeptical that typed throws will ever be adopted.

Let me emphasize that I love types and I love `Result`, which I've used in my own work. But defining a `Result` specific `Error` type doesn't make sense for Swift, not without some significant changes to the language. That's why I'm against this proposal.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [November 9, 2018, 4:18pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/125 "2018-11-09T16:18:27Z")

</div>

> [@anandabits](#):
>
> The throwing signature for the transform is effectively just different syntax for a transform that returns `Result<NewValue, Error>` . That is why this method has `flatMap` semantics. `compactMap` is a filtering map. I don't see any filtering happening here. 😉

In makes only sense to me if you treat the closure as another `Result`, but the flattening aspect of that is hidden and not obvious. I think that particular methods tried to merge the `init` and `flatMap` which is too much. I would drop that last `flatMap`.

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [November 9, 2018, 4:39pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/126 "2018-11-09T16:39:29Z")

</div>

There is another interesting performance consideration for unboxed Result types—they're not ideal for code size when propagated through many frames. Because unboxed `Result<T, U>` has a different size and layout for every `T` and `U`, propagating an error may require reconstructing a new `Result` into a different-sized indirect return buffer, or moving back and forth between register and in-memory returns. This is a problem in Rust, where Result is the idiomatic error propagation type; even simple error-propagating code spends a number of instructions moving pieces of `Result`s from one buffer to the next:

> **[Compiler Explorer - Rust (rustc 1.30.0)](https://rust.godbolt.org/z/fleECV)**
>
> extern { fn one\_int\_result() -\> Result; }
> 
> pub fn two\_int\_result() -\> Result\<(i64, i64), i64\> {
> Ok((unsafe {
> one\_int\_result()?
> }, 1234))
> }

Swift's `throws` avoids these issues by using a uniform boxed representation for `Error`, and a special calling convention that makes testing and propagating error results cheap; a Swift function can propagate an error by returning while leaving the existing error value in the error register (`r12` on x86-64):

> **[Compiler Explorer - Swift (x86-64 swiftc 4.1)](https://swift.godbolt.org/z/Q7WDYr)**
>
> @\_silgen\_name("one\_int\_result")
> func one\_int\_result() throws -\> Int
> 
> func two\_int\_result() throws -\> (Int, Int) {
> return (try one\_int\_result(), 1234)
> }

If we anticipate that people will want to use `Result` as a propagation mechanism, we many also want to consider whether it should be an `indirect enum`, which would give it a uniform representation that can be propagated more inexpensively. This would also give it a fixed layout so that it can be worked with uniformly in unspecialized generic code. The downside would be that constructing a Result would require boxing and allocating.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [November 9, 2018, 4:49pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/127 "2018-11-09T16:49:24Z")

</div>

> [@Joe\_Groff](#):
>
> If we anticipate that people will want to use `Result` as a propagation mechanism

I can't speak to the rest, but I don't think we will see `Result` propagated through many frames of a synchronous call stack. Certainly not if / when we add typed throws. `throws` is the right tool when that is what you want to do. `Result` will generally be used in other cases, or as you mentioned earlier, possibly when the `Result` is immediately handled.

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [November 9, 2018, 4:50pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/128 "2018-11-09T16:50:39Z")

</div>

Yeah, that's my feeling as well; my inclination would be to leave `Result` unboxed and recommend `throw`-ing anything you want to propagate further than a single frame.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [November 9, 2018, 5:30pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/129 "2018-11-09T17:30:57Z")

</div>

I want to clarify that I favor adding `Result` _only_ to address situations where manual propagation is necessary. Manual propagation will always occasionally be useful; adding `async`/`await` (or whatever we end up doing) will surely eliminate most of the most common situations, but they'll still exist, e.g. when using futures (which are the equivalent of manual propagation for `async`/`await` and accordingly trigger similar requirements).

I will continue to recommend against using `Result` as an alternative mechanism for ordinary propagation of errors, although I have no doubt that some people will insist on doing so; and I continue to believe that using a different error type than `Error` is generally misguided for the same reason it's generally misguided with ordinary error-handling. I also worry that the ergonomics of this type are significantly hurt by the attempt to support typed errors and (especially) non-`Error`-conforming errors.

But as someone who's thought quite a bit about error propagation, especially with regards to `async`/`await`, I have no doubt that `Result` will be a useful type even in that future.

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [November 9, 2018, 6:40pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/130 "2018-11-09T18:40:13Z")

</div>

I agree with not using `Result` as the primary error propagation mechanism, and I think that could be part of the Swift language documentation on error handling.

My implementation with a generic `Error` that's unconstrained was done for a few reasons:

1. It's the most flexible implementation, allowing the language to grow and change (typed errors, throwing non-Error types), while at the same time allowing use cases that can't be handled at all by the current system.
2. In the previous discussion thread (March 2018 timeframe), the proposal of an unconstrained `Result` was seen almost uniformly positively, as it cut the stalemate between the typed and untyped camps while unlocking previously impossible capabilities (non-Error error types).
3. The unconstrained form would allow easy aliases for both typed and untyped implementations, making transitioning from community implementations to the official one easier. Given the sheer amount of usage, this seems like a significant factor to me, though of course its importance is relative.

I've largely stood back from the discussion after the first bit, to see what responses brought up. But I did want to mention and reiterate a few things.

1. I largely aligned my implementation with common community implementations, in order to ease the transition build off the common knowledge of the type. However, I do think that changing the generic types to `Success`/`Failure` and their value accessors to `success`/`failure` would be acceptable, if those names are considered better. I found it hard to find guidance from the Swift naming guidelines in this case.
2. I wanted to build out a base level of convenience functionality that was common to the community types, as well as to types in the standard library, which is why it focuses mostly around `map` and other transforms. However, again, there are subtle differences between implementations and not a lot of guidance as to the most technically correct form some of them may take, so changes can be made if it's felt there are more proper forms. However, I do think this is a good base level of functionality that would allow the community to move to the standard implementation quickly.
3. If I understand the error manifesto (and other related discussion) correctly `Error` was not intended to be the end all be all error representation in Swift. It was chose and implemented the way it is in order to ease interop with `NSError`, as well as work easily with the automatic error propagation of `try`/`catch`. So I don't believe that all error handling in Swift should be limited to `Error` conforming types, even if that representation should form the vast majority of errors in Swift. This sort of simple/complex symmetry is reflected in other areas of Swift as well, so I don't believe it's unique to `Result`.

---

<div class="post-metadata">

**Author:** ![beccadax](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/beccadax/32/34217_2.png) [@beccadax](https://forums.swift.org/u/beccadax)\
**Post date:** [November 9, 2018, 7:50pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/131 "2018-11-09T19:50:56Z")

</div>

> [@Jon\_Shier](#):
>
> However, I do think that changing the generic types to `Success` / `Failure` and their value accessors to `success` / `failure` would be acceptable, if those names are considered better. I found it hard to find guidance from the Swift naming guidelines in this case.

FWIW, I don't agree that the generic types should be called `Success` and `Failure` or that the properties, if properties are included, should be called `success` and `failure`. The generic parameter of `Optional` is not called `Some`, and members that access it (like `unsafelyUnwrapped()`) do not refer to it as `some`.

> [@Jon\_Shier](#):
>
> If I understand the error manifesto (and other related discussion) correctly `Error` was not intended to be the end all be all error representation in Swift.

My reading of the error handling rationale is that `Error` is intended to at least include all "recoverable errors", which I think is what `Result` is intended to express. It even discusses converting universal and logic errors into `Error`s.

IMHO, `Error` is not a particularly limiting protocol and there's no strong reason to avoid requiring it. The only limitation it places is that types used as errors must be _declared_ to be error types—you can't just decide that you feel like throwing a `String` or a `Void` without publicly declaring that those types can be thrown. So allowing non-`Error` failure values just doesn't seem to me like a kind of flexibility we should care about.

(If we can't make `Error` existentials conform to `Error`, _that_ is definitely an obstacle, though.)

---

<div class="post-metadata">

**Author:** ![moiseev](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/moiseev/32/281_2.png) [@moiseev](https://forums.swift.org/u/moiseev)\
**Post date:** [November 9, 2018, 8:35pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/132 "2018-11-09T20:35:51Z")

</div>

Personally, I think an unconstrained `Result<T, E>` makes more sense, especially if we envision some error handling improvements and more magic happening around `async`/`await`, which will cover some of the use-cases of this type. It is not too hard to make a constrained typealias and use it exclusively getting access to all extensions that are conditional on `E: Error`; going in the other direction seems impossible without introducing a whole new type.

The name `Result` (and case names, too) seem to imply some sort of error-handling use. Rightfully so, but at the same time it limits the discoverability of the type for other uses. Who would reach for `Result` when they just want a general container of one of two things? `Either` sounds better for that, although I'm not a big fan of the usual `right`/`left` case names. Ideally I'd prefer `Either<One, TheOther>` as a "base" type and `Result<Value, Error: Error>` as it's subtype, with the cases renamed, which sounds impossible, at least now.

* * *

The important aspect that's missing from the proposal (and almost missing from the discussion) is that of code migration. It is great that the `Result` type as being proposed borrows best practices from existing and widely used implementations, but slight incompatibilities will make it not-quite-a-drop-in replacement. Manual migration will not be hard, but it will have to be done, and that's an annoyance. We have been trying really hard for the past couple years to not break existing source code. Even though we can't guarantee it in the presence of _any_ user code, in this case I believe we should try.

One possible solution would be to make the newly added type available only starting from Swift 5.0, so that all the existing uses will not become ambiguous; and then upon migration fully qualify all the mentions of the other `Result`. This way migrating the project to Swift 5 will not immediately require changing the code to adopt a new type. @akyrtzi might have better ideas.

---

<div class="post-metadata">

**Author:** ![akyrtzi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/akyrtzi/32/4963_2.png) [@akyrtzi](https://forums.swift.org/u/akyrtzi)\
**Post date:** [November 9, 2018, 9:06pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/133 "2018-11-09T21:06:22Z")

</div>

> [@moiseev](#):
>
> One possible solution would be to make the newly added type available only starting from Swift 5.0, so that all the existing uses will not become ambiguous; and then upon migration fully qualify all the mentions of the other `Result` .

@moiseev this seems like a good idea to me.

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [November 9, 2018, 9:57pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/134 "2018-11-09T21:57:25Z")

</div>

I didn't realize the migrator could support this case. Would anything be required on the type implementation side to support this, or would it be something separate? I'd be willing to give implementing a migrator a try, if there's a guide.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [November 9, 2018, 10:17pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/135 "2018-11-09T22:17:57Z")

</div>

I think a migrator that tried to recognize the common cases of third-party `Result` types would be really useful here. That seems like a reasonable precedent to set for whenever we pull common third-party libraries into Swift: we want to make it easy to adopt the standard solution, but we don't want Evolution to be hamstrung by a need to be drop-in source-compatible with the existing library.

Of course, I'm volunteering work for other people here. :)

---

<div class="post-metadata">

**Author:** ![moiseev](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/moiseev/32/281_2.png) [@moiseev](https://forums.swift.org/u/moiseev)\
**Post date:** [November 9, 2018, 10:35pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/136 "2018-11-09T22:35:33Z")

</div>

For the open source libraries that are willing to accept changes like that, it should be possible to simply annotate their `Result`s with `@available(swift, deprecated: 5.0, renamed: "Library.Result")`. Unless I'm mistaken, that should result in a compiler warning and a fix-it _while_ migrating. Obviously, that won't work for the user-defined `Result`s.

---

<div class="post-metadata">

**Author:** ![frameworklabs](https://avatars.discourse-cdn.com/v4/letter/f/13edae/32.png) [@frameworklabs](https://forums.swift.org/u/frameworklabs)\
**Post date:** [November 10, 2018, 1:50am UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/137 "2018-11-10T01:50:38Z")

</div>

Please add a typealias like this:

`public typealias Continuation = (Result<Value, Error>) -> Void`

This way methods taking completion handlers can be written:

`func aMethod(continuation: Result<SomeType, Error>.Continuation)`

Instead of:

`func aMethod(continuation: (Result<SomeType, Error>) -> Void)`

Besides that I am neutral (± 0) on the proposal. Result objects are somewhat low level and not used much once we move to Promises and async/await. Result objects might be used to implement Promises though.

---

<div class="post-metadata">

**Author:** ![Michael\_Brown](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michael_brown/32/2480_2.png) [@Michael\_Brown](https://forums.swift.org/u/Michael_Brown)\
**Post date:** [November 10, 2018, 9:29am UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/138 "2018-11-10T09:29:23Z")

</div>

> [@nicklockwood](#):
>
> I’m very strongly in favor of this proposal, and I’d prefer to keep the naming as-is.
> 
> A lot of the criticisms of the naming fail to acknowledge that the names that have been chosen are not arbitrary — the Result type is an established standard within the Swift community and has been for several years.
> 
> The naming of the cases and methods are recognized terms-of-art for many Swift developers, and changing them would mean that instead of a near drop-in-replacement for the existing Result types used in most projects, developers would need to make unnecessary breaking changes to their APIs.
> 
> - What is your evaluation of the proposal?
> 
> I agree with the design and rationale for the API as proposed.
> 
> - Is the problem being addressed significant enough to warrant a change to Swift?
> 
> Very much so. I use some form of Result for basically every project I work on, and the fact that it can’t be conveniently exposed in public APIs without either adding a dependency on a 3rd party framework or requiring consumers to manually convert between different Result types with near-identical APIs is a constant frustration.
> 
> - Does this proposal fit well with the feel and direction of Swift?
> 
> Yes. It is paving a well-trodden cowpath within the Swift development community.

I agree 100% with @nicklockwood’s evaluation. I very rarely comment on evolution proposals but I feel so strongly in favour of adding `Result` that I had to show my support.

I cannot imagine working on a project without a `Result` type. The implementation as proposed closely matches the implementation I most [most commonly use](https://github.com/antitypical/Result).

I have been following the discussion about adding Result to the standard library for some time.

---

<div class="post-metadata">

**Author:** ![Geordie\_J](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/geordie_j/32/839_2.png) [@Geordie\_J](https://forums.swift.org/u/Geordie_J)\
**Post date:** [November 10, 2018, 7:40pm UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/139 "2018-11-10T19:40:01Z")

</div>

FWIW I’m -1 on this.

The proposal is well-written and clean and, _if_ a Result Type should be added to the standard library I can imagine it being along these lines (though maybe with a little less API and a little more internal naming consistency) BUT, I personally don’t see any value in a Result type at all going forward, and mirror others’ arguments in that I believe it will complicate Swift’s error handling unnecessarily.

The main proposal seems to be “try/catch doesn’t work async”. Excuse my bluntness but why don’t we “just” make try/catch work with async? I’m going to be unpopular here for bringing up (horror) JavaScript but aside from some hairy edges I quite like how they’ve adapted try/catch to work with async/await in recent language versions.

If the Result syntax is useful in making up for current shortcomings but is mainly a stepping stone for async/await or actors or whatever concurrency primitives we may end up with, why not leave them as an unexposed implementation detail once that proposal lands?

I think cleaning up other projects’ use of their own Result types - which has also arisen due to lack of first class concurrency - should explicitly be a non-goal here. Let’s not end up like C++ with multiple imperfect ways of achieving much the same thing.

---

<div class="post-metadata">

**Author:** ![danielhall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/danielhall/32/29455_2.png) [@danielhall](https://forums.swift.org/u/danielhall)\
**Post date:** [November 11, 2018, 4:59am UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/140 "2018-11-11T04:59:52Z")

</div>

> What is your evaluation of the proposal?

I’m in favor of adding the missing basic type that sits somewhere between Optional and tuple, and represents a value of _either_ one generic type OR a second generic type. So basically a Haskell Either type as has been mentioned a couple of times. I’m **not** in favor of spelling this type “Result” or naming its cases things like “error” or “failure” or “success”, which are much more opinionated and limited abstractions than an “Either” type.

- Essentially every benefit and use case of a Result type is equally served by a more abstractly named Either type. However, the reverse is not true, i.e. a “Result” type with cases that imply only success / failure or value / error are not abstractions that serve well for all places where an Either type could be useful.

- Naming this type “Result” and having an “Error” case or generic type name strongly suggests that this _should_ be used for error handling and / or propagation. As others have noted, I’m not sure that’s in line with where Swift is going and it essentially leaves a sort of ambiguity. Without Cocoa Touch and other Standard Library APIs making use of Result, it feels like a tacked-on oddity and somewhat dead on the vine.

- On the other hand, having the equivalent of a Haskell “Either” type would be useful regardless of future error handling and Async/Await implementations. And I could easily see such a type being used appropriately in first party APIs just as Optional and tuple are today. In other words, an Either type is a fundamental concept and a generalized enough abstraction that I don’t think it would be controversial to add to the standard library, and it would clearly be useful across many different scenarios without getting boxed into an ambiguous role as being an unofficial (and clearly unsanctioned) alternative to `throws`. And assuming an Either type did make it into the standard library, 100% of the uses and benefits of this proposed Result type could be accomplished using it, satisfying that need for those who want to use that kind of abstraction for their own frameworks and API.

- Not to get TOO philosophical, but the naming of typical Result types and their cases still subtly encourage happy-path only coding and make it only slightly (if at all) more difficult to ignore errors. And this proposal even goes further down that path with additional API that favors only checking for success . A big part of the conceptual rationale for Result is that it’s vital for code to check and handle the error case as being equally possible and valid as the success case. And that rationale is better served by a naming like Either, which makes it clear that a result isn’t going to be (probably) a success or (hopefully not) an error or failure, but rather one of two equally important and equally valid values.

- The proposal quickly mentions and then dismisses an Either type in the alternatives considered section, with the reasoning for discarding this possibility being that there is an indepedent open source Either library for Swift which has far fewer downloads than the leading Result library. I don’t find this reason for dismissing the Either alternative compelling.

> Is the problem being addressed significant enough to warrant a change to Swift?

Lacking a basic functional abstraction like Either is definitely a significant problem, made evident as noted by how many frameworks and apps have rolled their own version of it. However, I again want to point out that I see the problem as not having an Either type, not as lacking a “Result” type, which is a more limited naming and conceptual abstraction.

> Does this proposal fit well with the feel and direction of Swift?

Again, having a type that can _function_ as proposed fits well, but I don’t care for the naming, which I don’t think fits well. Swift has adapted Haskell’s “Maybe” to “Optional”, and I think it would be completely logical and consistent to adapt “Either” to something equivalent as well. The proposal even avoids constraining the generic error case type to conform to Swift.Error in order to let Result be used for other scenarios that don’t involve error handling. But if we recognize that such a need exists, then we shouldn’t keep the Result / Success / Failure / Error naming at all.

This is subjective, but I can imagine various syntactic and compiler sugar for an Either type being added to Swift just as was done for the Optional type. And I can imagine the Standard Library and Cocoa API that would make use of a generalized Either type, just as they do with the Optional type today. But I find it hard to imagine consistent and widespread adoption of a Result type in Cocoa or the Standard Library.

> If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I prefer the Either type in Haskell. It feels like a foundational computer science concept and data type that is both self explanatory and non-controversial as a building block for all kinds of code. A Result type on the other hand is controversial, less abstract, more opinionated and yet not in any way more capable or correct.

> How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Quick reading through the whole proposal, and I read the 137 comments currently on this thread.

---

<div class="post-metadata">

**Author:** ![zwaldowski](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/zwaldowski/32/21801_2.png) [@zwaldowski](https://forums.swift.org/u/zwaldowski)\
**Post date:** [November 11, 2018, 5:25am UTC](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/141 "2018-11-11T05:25:22Z")

</div>

Soft -1.

I am reluctantly open to a `Result` type in the Standard Library. This one makes trade-offs I'm not thrilled with.

The Standard Library should indeed seek to capture near-ubiquitous patterns. Though, I would rather investments continue to be made into the Swift error handling rather than undermining it. Swift's feature domains are meant to compose well, provide benefit to the programmer, and meet Swift's goals as a language. If error handling is not meeting that standard, that's a problem.

Now, that's all pie-in-the-sky. The future isn't now, now is now, and `Result` is very common. This _is_ a problem worth addressing in the language, for now, as sad as I am about needing to commit to a simple two-case enum in the ABI.

On a few points, I don't feel like it fits well with Swift's feel and direction. Sometimes, it's like trying to change that direction by fiat. The proposal mentions throwing not-`Error`s as a future direction a few times, and I'd absolutely call that a non-goal. Likewise, and more significantly, I strongly feel like the `Error` generic parameter argument to `Result` is undesirable and fighting against the language.

As an aside, I'll recall my post [earlier](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752/44) that the proposal doesn't meet its own goal of eliminating duplication in third-party libraries because a generic doesn't compose as a `where` clause. Not the proposal's fault, `Optional` has the same problem. I mention it here because I suspect the needless `ResultProtocol` clones is what lead to `fold`.

Some drive-by notes that I don't feel strongly about:

- Not a fan of `unwrapped()`. It doesn't describe what it's doing meaningfully, nor what it's returning.
- I agree with the monadic methods having their parameters be `throws`. `rethrows` is arguable, I think the desired behavior is to re-wrap but I'm not 100% sure.
- `mapError` and `flatMapError` aren't compelling names. I don't think either name is something you'd reach for naturally and they lack symmetry with the non-error variants.
- `fold` is borderline-silly. We don't need a function call to abstract over `switch`. We already have `switch`, it's great.

[Previous page](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752.md?page=6)

[Next page](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752.md?page=8)
