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

Kevin Ballard kevin at sb.org
Wed Jan 27 21:15:04 CST 2016


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?).

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.

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.

-Kevin Ballard
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160127/9bf181fe/attachment.html>


More information about the swift-evolution mailing list