All:
        I’ve updated the proposal to include a better introduction and examples 
of Result usage to better justify its inclusion in the standard library.

Re: Result<T, E> & typed throws
        This seems to be the most contentious part of this proposal. As 
explained in the proposal, Result<T> allows painless usage with all current 
Swift APIs, especially Apple’s. At worst, this version of Result requires 
casting the Error value to a concrete type if you need to do something with 
that error. I believe that tradeoff is worthwhile, since it guarantees painless 
integration with APIs that return multiple error types, return undocumented 
error types, reserve the right to change error types, or otherwise just return 
Error. While Result<T, E> could work here, I usually see it done by casting an 
unknown error to NSError, which, to me, is an anti pattern. A possible solution 
here is the introduction of an AnyError type that could be used to wrap any 
unknown errors in a concrete type. Such a type presents usability concerns, as 
using it automatically would be difficult, requiring users to manually wrap 
unknown errors.
        This consideration is further complicated by the possible addition of 
typed throws in the future. However, the most commonly suggested implementation 
fo typed throws keeps the ability for throws to be untyped. Additionally, the 
feature usually allows multiple types to be thrown from a single function. 
Result<T> can handle all of these scenarios automatically, since it reduces all 
errors down to Error. A Result<T, E> however, would either lose the ability to 
encapsulate any function with multiple error types, or otherwise have to wrap 
those cases in something like AnyError, in additional to having to do so in the 
untyped case. It seems likely to me that this would become the more common 
case, losing most of the elegance of Result<T, E> in exchange for those rare 
scenarios where a single typed error is known. However, I would like input from 
the core team here.
        Finally, part of any Swift Result type should be the ability to turn a 
Result back into a throwing function. Addition of an AnyError wrapper would 
greatly complicate this usage of a Result<T, E> type, as the user would have to 
attempt a cast to AnyError, then cast the contained error to a concrete type. 
Given what would probably be frequent usage of AnyError, this is a rather 
glaring ergonomic issue.

Re: Result and future async/await
        While I’m not intimately familiar with the whole of the current async 
proposal, I believe it’s possible it can be rectified with Result. Similar to 
how Result acts as a manually propagated error solution, it could do the same 
to the propagation of async results and errors. Result could capture the result 
of said executions, especially if the keywords could be applied to 
initializers: await Result { async String(url:…) }. This would have many of the 
same use cases I’ve outlined in the proposal in regards to throwing functions. 
Additionally, unless the plan is to automatically convert all current async 
APIs in Swift or Apple’s frameworks to the async / await model, Result would 
still have a place in handling older style APIs using completion handlers and 
such.

Re: Deeper integration with the Standard Library
        This proposal includes the most common functionality included with 
Result implementations available to the community. Given the lack of deeper 
integration attempted, I’m not sure how far such integration should or needs to 
go. But I’ll respond to some commonly suggested ones and offer some of my own 
here.
        • Convenience Operators: To be honest, I’m not sure this is necessary. 
None of the Result libraries I’ve seen have implemented such a thing and I’m 
not sure why it would be necessary. The proposed Result type already includes 
the ability to wrap a throwing closure and to unwrap a Result using try. So I 
guess a better outline of what, exactly, would be more convenient about such an 
operator would be appreciated. Perhaps some variant of the ternary operator? 
But this is all about hiding the enum nature of Result, like Optional does, 
right? 
        • Reconcile () -> Result<T> and () throws -> T: To be honest, I’m not 
even sure where to start here. Personally I’d think something like this would 
be separate from the introduction of Result, given the fundamental change to 
language syntax this would represent. Would this equivalence be similar to any 
other feature in Swift? I can’t think of any.
        One convenience feature I have used are APIs on Collection to deal with 
collections of Results. This is useful when needing to operate on all of the 
values or errors. Another bit I really didn’t touch on, but which could be 
hugely useful, is the automatic conversion of completion handlers in imported 
Objective-C APIs to use Result. This would a huge, and somewhat dangerous 
undertaking, but something which greatly improve those APIs.
        My biggest concern here is that expanding the proposal beyond just 
introducing the type and perhaps some top level convenience APIs, like the 
Collection API mentioned, greatly increases the language impact and 
implementation effort. I’d like to keep the proposal to just what’s necessary 
to introduce the type and add language or convenience features around it in the 
future as targeted proposals, rather than one giant one that encompasses 
everything all at once.



Jon


> On Nov 5, 2017, at 6:40 AM, Rod Brown <rodney.bro...@icloud.com> wrote:
> 
> I was thinking the same thing. Typed throws vs `Error` throws are the two 
> major differences between different Result implementations, and they seem 
> somewhat tied from a discussion perspective.
> 
> I agree with others here, I would like to see this added to the library, and 
> I think it’s a generally valuable type that has broad uses beyond the 
> completion handler solution that it’s commonly been used for. But if we add 
> things to do the standard library, they need to be consistent, with the 
> direction of Swift, and that’s a big call at this stage to either write in or 
> out typed throws...
> 
> Rod
> 
> On 3 Nov 2017, at 2:41 pm, Chris Lattner via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
>> 
>>> On Nov 2, 2017, at 11:08 AM, Jon Shier via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Swift-Evolution:
>>>     I’ve written a first draft of a proposal to add Result<T> to the 
>>> standard library by directly porting the Result<T> type used in Alamofire 
>>> to the standard library. I’d be happy to implement it (type and tests for 
>>> free!) if someone could point me to the right place to do so. I’m not 
>>> including it directly in this email, since it includes the full 
>>> implementation and is therefore quite long. (Discourse, please!) 
>>> 
>>> https://github.com/jshier/swift-evolution/blob/master/proposals/0187-add-result-to-the-standard-library.md
>>>  
>>> <https://github.com/jshier/swift-evolution/blob/master/proposals/0187-add-result-to-the-standard-library.md>
>> I’m generally supportive of this, but the design of such a thing forces 
>> another contentious issue: whether the error handling model should be 
>> extended to support "typed throws”.  Without result, we can carry on pushing 
>> the "typed throws” debate down the road.  Adding it would force that issue 
>> to be decided, which is complicated.
>> 
>> -Chris
>> 
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to