[swift-evolution] [proposal] Either in the Swift Standard Library

Matthew Johnson matthew at anandabits.com
Thu Jan 28 08:15:49 CST 2016


> On Jan 27, 2016, at 9:15 PM, Kevin Ballard via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Note: I'm going to talk about the Result<T,E> type here, which is somewhat tangential to this thread as this thread is not in fact proposing Result<T,E>, and I'm not expecting to have a real discussion about how Result<T,E> would be designed at this point. I'm just writing my thoughts down as a reply to Chris Lattner. This can be explored more fully at such time as we do try to develop a concrete proposal for a Result<T,E> type.
>  
> On Tue, Jan 26, 2016, at 10:31 PM, Chris Lattner wrote:
>>> You know my counterarguments about the name.  But at this point as long as I get an unconstrained Result in two type parameters I'm fine because that's the structure we are advocating for in the proposal.  
>>  
>> To set expectations, I’d expect the Result type to be specifically designed to serve the problem domain of capturing a return value.  Even assuming we get “typed throws”, I’d expect the error argument to have an ErrorType constraint on it.  Further, if we expand the function result type model, we’d expect Result to track that.  I would also expect the Result type to have methods on it specific to its domain.
>>  
>> This means that it will not be unconstrained, and not a generic type like the Either you are proposing.
>  
> I'd prefer to have an unconstrained Result<T,E> that has extensions for E: ErrorType. I don't think there's any particular value in defining the type itself as Result<T, E: ErrorType> because most of the methods won't care about the ErrorType bounds, and the methods that we'd want to have that do care about it aren't crucial to the basic operation of the type. Having it unconstrained will also allow people to use Result<T,ErrorType> (given that existential protocol values don't conform to the protocol, although I haven't been following everything so maybe there's already plans to change that?).

I’m pretty sure existentials not conforming to the protocol is considered a non-trivial implementation issue.  I think there is desire to do that eventually, but I don’t think there are concrete plans yet (unless there has been core team work that hasn’t been discussed).  

>  
> However, doing this properly with an unconstrained Result<T,E> does run into the limitation where you can't say `extension Result where E == ErrorType` to add methods for when E is the ErrorType existential (though if we do change it so the ErrorType existential conforms to ErrorType then `extension Result where E: ErrorType` will work just fine). We'd probably also want to add support for generic parameters on typealiases, so you can say `typealias FooResult<T> = Result<T, FooError>`.
>  
> There's also some questions about how this would interact with "typed throws" (assuming we get typed throws), e.g. if a function can return one of 3 different error types, how would you represent this with a Result<T,E> (short of manually defining a new enum with a variant for each case), and so if we are going to get "typed throws" then it makes some sense to wait until we have some idea of how that's going to work before designing a Result type that expects to interact with errors.

Throwing multiple error types was discussed pretty extensively in a couple of threads, one of which was the thread for David’s typed throws proposal.  The short answer is that it won’t be possible directly.  We will need to manually define an enum like you mentioned, at least at first.  If Swift ever adds support for structural sum types and those conform to ErrorType when all of the types conform to ErrorType then we could use a structural sum rather than manually defining one.

>  
> All that said, I don't feel all that strongly about this. I'd guess that most uses of Result would have either the ErrorType existential or some type that conforms to ErrorType as the E parameter even if Result is unconstrained, so constraining it as Result<T,E: ErrorType> isn't too limiting, but it does just seem like an unnecessary restriction as far as defining the Result type itself goes.

I think E would nearly always conform to ErrorType.  Do you have any examples in mind of why you would want to use something for E that can’t conform to ErrorType (aside from the existential)?

-Matthew

>  
> -Kevin Ballard
> _______________________________________________
> 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