[swift-evolution] throws as returning a Result

Joe Groff jgroff at apple.com
Mon Mar 14 12:23:49 CDT 2016


> On Mar 14, 2016, at 5:15 AM, Thomas Guthrie via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
>> On 14 Mar 2016, at 11:36, Ondrej Barina via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>> 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?).
> 
> Result is mentioned in https://github.com/apple/swift/blob/master/docs/ErrorHandling.rst#manual-propagation-and-manipulation-of-errors <https://github.com/apple/swift/blob/master/docs/ErrorHandling.rst#manual-propagation-and-manipulation-of-errors> (the proposal/doc for swift’s current error handling) and John McCall had this to say about it:
> 
>> We considered it, had some specifics worked out, and then decided to put it on hold.  Part of our reasoning was that it seemed more like an implementation detail of the async / CPS-conversion features we’d like to provide than an independently valuable feature, given that we don’t want to encourage people to write library interfaces using functional-style error handling instead of throws.
>> 
>> It’s also a feature that’s directly affected by the design of typed throws, which in turn poses some usability challenges for it.  For example, without typed throws you really just want the type to be Result<T>.  With typed throws, can you still write that, or do you have to write Result<T, ErrorType>?  Also, if we want every function result signature to have a corresponding Result<> type, does that permanently prevent us to supporting multiple error types with “typed throws”?  Also, would it be too frustrating to work with typed Result values if we don’t allow implicit covariant conversions along one or both dimensions?
> 
> (From https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/001433.html <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/001433.html>)

Yeah, we extensively discussed adding a Result type internally, but ultimately couldn't justify it. The only real use case we could see in the wild was for threading errors through CPS-inversion-style abstractions like async promises, something we hope to provide proper language support for. More generally, expressing effects as monadic values is a pretty awful abstraction; aside from polluting the Internet with an endless deluge of unhelpful tutorials, they also don't compose cleanly, they impose nesting where is desired—you have to pick between Result<Async<T>> and Async<Result<T>>, or build ResultT<AsyncT<Identity>><T> out of monad transformers—and they don't do the natural thing when used with other higher-order abstractions—if you're mapping a `throws` function over a collection, you probably want to propagate that error like `rethrows` does, not end up with a collection of Result<T>. I'd rather see us adopt an extensible algebraic effects system, something like http://www.eff-lang.org, which provides a framework for `throws`, `async` and other control flow effects to be cleanly composed and abstracted over. I see `throws` as the first seed of that.

-Joe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160314/969b52f6/attachment.html>


More information about the swift-evolution mailing list