[swift-evolution] throws as returning a Result

Ondrej Barina obarina at gmail.com
Mon Mar 14 06:36:13 CDT 2016


I am for Automatic propagation/conversion.
if this line works:

let a : Result<Foo> = try makeFoo(42)

it would be great usage of Result. (there was discussion about it. I
think it was rejected).

Not really sure about:  "let a: Result<Foo> = makeFoo(42)"
I can see that this could become more needed/used when we are going
towards async coding in next Swift (4.0?).

Ondrej B.



On Mon, Mar 14, 2016 at 12:07 PM, Yuta Koshizawa via swift-evolution
<swift-evolution at swift.org> wrote:
> I think it would be great if throws -> Foo were a syntactic sugar of ->
> Result<Foo>. Without affecting existing codes, it makes it possible to go
> back and forth between Manual Propagation and Automatic Propagation
> seamlessly.
>
> // I wish if the first `makeFoo` were
> // a syntactic sugar of the second one
> func makeFoo(x: Int) throws -> Foo {
>   guard ... else {
>     throw FooError()
>   }
>   return Foo(x)
> }
> // @warn_unused_result
> // func makeFoo(x: Int) -> Result<Foo> {
> //   guard ... else {
> //     return Result(error: FooError())
> //   }
> //   return Result(Foo(x))
> // }
>
> // Manual propagation
> let result: Result<Foo> = makeFoo(42) // without `try`
> switch result {
>   case let .Success(foo):
>     ...
>   case let .Failure(error):
>     ...
> }
>
> // Automatic propagation
> do {
>   let foo: Foo = try makeFoo(42) // with `try`: a kind of unwrapping
>   ...
> } catch let error {
>   ...
> }
>
> For what?
>
> I want to unify throws and Result into one feature to keep the language
> simple.
>
> As referred in "Error Handling Rationale and Proposal", I think Swift should
> provide something like Result. It means we would have similar two features:
> throws and Result. We need a way to covert them to each other. For examples,
> it can be done in the following way.
>
> // What I DON'T want
> func makeFoo(x: Int) throws -> Foo { ... } // -> Result<Foo>
>
> let a: Result<Foo> = try| makeFoo(42)
>   // `try|` for `Result` like `try?` for `Optional`
>
> do {
>   let b = try a.throwIfError()
>   ...
> } catch let error {
>   ...
> }
>
> If throws were a syntactic sugar of returning a Result, it would be simpler.
>
> // What I want
> func makeFoo(x: Int) throws -> Foo { ... } // -> Result<Foo>
>
> let a: Result<Foo> = makeFoo(42)
>
> do {
>   let b = try a
>   ...
> } catch let error {
>   ...
> }
>
> In Addition, it prevents that APIs of third-party libraries diverge. If we
> had similar but different two features, throws and Result, some libraries
> would use throws and others would use Result. Actually it has already
> happened. Some popular libraries use antitypical/Result or their own Result
> types. If throws were a syntactic sugar of returning a Result, using throws
> or Result would affect only the appearance of codes, and we could use those
> libraries in the same way.
>
>
> -- Yuta
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>


More information about the swift-evolution mailing list