Proposal: An Either Type in the STL


(Robert Widmann) #1

It’s high time the STL admitted some kind of disjoint union type, at the very least because it’s such a minor addition it seems a shame to leave it out. Whatever feelings one may have about `throws`, the lack of standardizing on a datatype representing choice has caused the community to get creative and create many disjoint implementation of the same concept over and over and over again. To that end, I propose the STL ship with an Either type; We at TypeLift have already got our own we’d like to model it on (https://github.com/typelift/Swiftx/blob/master/Swiftx/Either.swift#L16).

~Robert Widmann (CodaFi)


Sum-tuples
(Ilias Karim) #2

Hi Robert,

I agree with your recommendation of a generic Either type.

However, I find your use of “Right” as the “Correct” value (whatever that means) of an instance of an Either type a little perplexing. While clever, it is exactly the kind of convention that easily leads to misunderstandings about the nature of the type itself ie. is it right and left or wrong and correct? At least that is my first impression after scanning your code.

Ilias

···

On Dec 9, 2015, at 3:06 PM, Developer via swift-evolution <swift-evolution@swift.org> wrote:

It’s high time the STL admitted some kind of disjoint union type, at the very least because it’s such a minor addition it seems a shame to leave it out. Whatever feelings one may have about `throws`, the lack of standardizing on a datatype representing choice has caused the community to get creative and create many disjoint implementation of the same concept over and over and over again. To that end, I propose the STL ship with an Either type; We at TypeLift have already got our own we’d like to model it on (https://github.com/typelift/Swiftx/blob/master/Swiftx/Either.swift#L16).

~Robert Widmann (CodaFi)
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jacob Bandes-Storch) #3

The idea of using Left/Right is to remain agnostic to what sorts of things
users might want to put in. It's feasible a user might want Either<Int,

, not just Either<ErrorType, T>.

While I'm not sure Left & Right are the best choices, I don't think it's
particularly worrisome when it comes to errors, as the general type-safety
of the language will prevent users from mixing up success & error cases.

Jacob

···

On Wed, Dec 9, 2015 at 3:32 PM, Ilias Karim via swift-evolution < swift-evolution@swift.org> wrote:

Hi Robert,

I agree with your recommendation of a generic Either type.

However, I find your use of “Right” as the “Correct” value (whatever that
means) of an instance of an Either type a little perplexing. While clever,
it is exactly the kind of convention that easily leads to misunderstandings
about the nature of the type itself ie. is it right and left or wrong and
correct? At least that is my first impression after scanning your code.

Ilias

> On Dec 9, 2015, at 3:06 PM, Developer via swift-evolution < > swift-evolution@swift.org> wrote:
>
> It’s high time the STL admitted some kind of disjoint union type, at the
very least because it’s such a minor addition it seems a shame to leave it
out. Whatever feelings one may have about `throws`, the lack of
standardizing on a datatype representing choice has caused the community to
get creative and create many disjoint implementation of the same concept
over and over and over again. To that end, I propose the STL ship with an
Either type; We at TypeLift have already got our own we’d like to model it
on (https://github.com/typelift/Swiftx/blob/master/Swiftx/Either.swift#L16
).
>
>
> ~Robert Widmann (CodaFi)
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


(Ilias Karim) #4

What are the advantage over using a tuple? One great feature about tuples is being able to name parameters so you can dispel ambiguity.

···

On Dec 9, 2015, at 3:35 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

The idea of using Left/Right is to remain agnostic to what sorts of things users might want to put in. It's feasible a user might want Either<Int, String>, not just Either<ErrorType, T>.

While I'm not sure Left & Right are the best choices, I don't think it's particularly worrisome when it comes to errors, as the general type-safety of the language will prevent users from mixing up success & error cases.

Jacob

On Wed, Dec 9, 2015 at 3:32 PM, Ilias Karim via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hi Robert,

I agree with your recommendation of a generic Either type.

However, I find your use of “Right” as the “Correct” value (whatever that means) of an instance of an Either type a little perplexing. While clever, it is exactly the kind of convention that easily leads to misunderstandings about the nature of the type itself ie. is it right and left or wrong and correct? At least that is my first impression after scanning your code.

Ilias

> On Dec 9, 2015, at 3:06 PM, Developer via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> It’s high time the STL admitted some kind of disjoint union type, at the very least because it’s such a minor addition it seems a shame to leave it out. Whatever feelings one may have about `throws`, the lack of standardizing on a datatype representing choice has caused the community to get creative and create many disjoint implementation of the same concept over and over and over again. To that end, I propose the STL ship with an Either type; We at TypeLift have already got our own we’d like to model it on (https://github.com/typelift/Swiftx/blob/master/Swiftx/Either.swift#L16).
>
>
> ~Robert Widmann (CodaFi)
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


(Jacob Bandes-Storch) #5

A tuple of (A?, B?) has four states: (nil, nil) / (A, nil) / (nil, B) / (B,
nil)

Whereas Either<A,B> has only two states: .Left(A) or .Right(B).

Jacob

···

On Wed, Dec 9, 2015 at 3:41 PM, Ilias Karim <ilias.karim@gmail.com> wrote:

What are the advantage over using a tuple? One great feature about tuples
is being able to name parameters so you can dispel ambiguity.

On Dec 9, 2015, at 3:35 PM, Jacob Bandes-Storch <jtbandes@gmail.com> > wrote:

The idea of using Left/Right is to remain agnostic to what sorts of things
users might want to put in. It's feasible a user might want Either<Int,
>, not just Either<ErrorType, T>.

While I'm not sure Left & Right are the best choices, I don't think it's
particularly worrisome when it comes to errors, as the general type-safety
of the language will prevent users from mixing up success & error cases.

Jacob

On Wed, Dec 9, 2015 at 3:32 PM, Ilias Karim via swift-evolution < > swift-evolution@swift.org> wrote:

Hi Robert,

I agree with your recommendation of a generic Either type.

However, I find your use of “Right” as the “Correct” value (whatever that
means) of an instance of an Either type a little perplexing. While clever,
it is exactly the kind of convention that easily leads to misunderstandings
about the nature of the type itself ie. is it right and left or wrong and
correct? At least that is my first impression after scanning your code.

Ilias

> On Dec 9, 2015, at 3:06 PM, Developer via swift-evolution < >> swift-evolution@swift.org> wrote:
>
> It’s high time the STL admitted some kind of disjoint union type, at
the very least because it’s such a minor addition it seems a shame to leave
it out. Whatever feelings one may have about `throws`, the lack of
standardizing on a datatype representing choice has caused the community to
get creative and create many disjoint implementation of the same concept
over and over and over again. To that end, I propose the STL ship with an
Either type; We at TypeLift have already got our own we’d like to model it
on (
https://github.com/typelift/Swiftx/blob/master/Swiftx/Either.swift#L16).
>
>
> ~Robert Widmann (CodaFi)
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


(Ilias Karim) #6

I’m sorry, I misunderstood. I guess an enum would be the appropriate choice, instead.

As far as left/right goes, the decision to have left or right be the “correct” value is entirely arbitrary and should be left up to the developer. It should be a convention at best.

Ilias

···

On Dec 9, 2015, at 3:43 PM, Dave DeLong <delong@apple.com> wrote:

With a tuple, you have to do “(left: T?, right: U?)”, whereas with an Either you are guaranteed to always have one or other other; never both and never neither. That is not guaranteed with the tuple.

Dave

On Dec 9, 2015, at 4:41 PM, Ilias Karim via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

What are the advantage over using a tuple? One great feature about tuples is being able to name parameters so you can dispel ambiguity.

On Dec 9, 2015, at 3:35 PM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

The idea of using Left/Right is to remain agnostic to what sorts of things users might want to put in. It's feasible a user might want Either<Int, String>, not just Either<ErrorType, T>.

While I'm not sure Left & Right are the best choices, I don't think it's particularly worrisome when it comes to errors, as the general type-safety of the language will prevent users from mixing up success & error cases.

Jacob

On Wed, Dec 9, 2015 at 3:32 PM, Ilias Karim via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hi Robert,

I agree with your recommendation of a generic Either type.

However, I find your use of “Right” as the “Correct” value (whatever that means) of an instance of an Either type a little perplexing. While clever, it is exactly the kind of convention that easily leads to misunderstandings about the nature of the type itself ie. is it right and left or wrong and correct? At least that is my first impression after scanning your code.

Ilias

> On Dec 9, 2015, at 3:06 PM, Developer via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> It’s high time the STL admitted some kind of disjoint union type, at the very least because it’s such a minor addition it seems a shame to leave it out. Whatever feelings one may have about `throws`, the lack of standardizing on a datatype representing choice has caused the community to get creative and create many disjoint implementation of the same concept over and over and over again. To that end, I propose the STL ship with an Either type; We at TypeLift have already got our own we’d like to model it on (https://github.com/typelift/Swiftx/blob/master/Swiftx/Either.swift#L16).
>
>
> ~Robert Widmann (CodaFi)
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

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

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


(Dave DeLong) #7

With a tuple, you have to do “(left: T?, right: U?)”, whereas with an Either you are guaranteed to always have one or other other; never both and never neither. That is not guaranteed with the tuple.

Dave

···

On Dec 9, 2015, at 4:41 PM, Ilias Karim via swift-evolution <swift-evolution@swift.org> wrote:

What are the advantage over using a tuple? One great feature about tuples is being able to name parameters so you can dispel ambiguity.

On Dec 9, 2015, at 3:35 PM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

The idea of using Left/Right is to remain agnostic to what sorts of things users might want to put in. It's feasible a user might want Either<Int, String>, not just Either<ErrorType, T>.

While I'm not sure Left & Right are the best choices, I don't think it's particularly worrisome when it comes to errors, as the general type-safety of the language will prevent users from mixing up success & error cases.

Jacob

On Wed, Dec 9, 2015 at 3:32 PM, Ilias Karim via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hi Robert,

I agree with your recommendation of a generic Either type.

However, I find your use of “Right” as the “Correct” value (whatever that means) of an instance of an Either type a little perplexing. While clever, it is exactly the kind of convention that easily leads to misunderstandings about the nature of the type itself ie. is it right and left or wrong and correct? At least that is my first impression after scanning your code.

Ilias

> On Dec 9, 2015, at 3:06 PM, Developer via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> It’s high time the STL admitted some kind of disjoint union type, at the very least because it’s such a minor addition it seems a shame to leave it out. Whatever feelings one may have about `throws`, the lack of standardizing on a datatype representing choice has caused the community to get creative and create many disjoint implementation of the same concept over and over and over again. To that end, I propose the STL ship with an Either type; We at TypeLift have already got our own we’d like to model it on (https://github.com/typelift/Swiftx/blob/master/Swiftx/Either.swift#L16).
>
>
> ~Robert Widmann (CodaFi)
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

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

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


(John McCall) #8

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?

John.

···

On Dec 9, 2015, at 3:45 PM, Guillaume Lessard via swift-evolution <swift-evolution@swift.org> wrote:
There is probably a greater need for a non-agnostic Result monad type (with descriptive cases .Value and .Error) for manual error propagation. If it’s not agnostic then the happy and unhappy paths can be better optimized.

Such a type was proposed but not designed in <https://github.com/apple/swift/blob/master/docs/ErrorHandling.rst#manual-propagation-and-manipulation-of-errors>. Was it abandoned or simply left for later?
(There are several implementations available on github, heh)


(Guillaume Lessard) #9

There is probably a greater need for a non-agnostic Result monad type (with descriptive cases .Value and .Error) for manual error propagation. If it’s not agnostic then the happy and unhappy paths can be better optimized.

Such a type was proposed but not designed in <https://github.com/apple/swift/blob/master/docs/ErrorHandling.rst#manual-propagation-and-manipulation-of-errors>. Was it abandoned or simply left for later?
(There are several implementations available on github, heh)

Guillaume Lessard


(Robert Widmann) #10

A tuple is a product, we want a sum here. A tuple says “I know I have 2 things”, a sum says “I know one or the other of these things is here but not both” without the need to unwrap both halves just to check. Past a certain point, you’re writing Either code over and over again without realizing it.

···

On Dec 9, 2015, at 6:41 PM, Ilias Karim <ilias.karim@gmail.com> wrote:

What are the advantage over using a tuple? One great feature about tuples is being able to name parameters so you can dispel ambiguity.

On Dec 9, 2015, at 3:35 PM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

The idea of using Left/Right is to remain agnostic to what sorts of things users might want to put in. It's feasible a user might want Either<Int, String>, not just Either<ErrorType, T>.

While I'm not sure Left & Right are the best choices, I don't think it's particularly worrisome when it comes to errors, as the general type-safety of the language will prevent users from mixing up success & error cases.

Jacob

On Wed, Dec 9, 2015 at 3:32 PM, Ilias Karim via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hi Robert,

I agree with your recommendation of a generic Either type.

However, I find your use of “Right” as the “Correct” value (whatever that means) of an instance of an Either type a little perplexing. While clever, it is exactly the kind of convention that easily leads to misunderstandings about the nature of the type itself ie. is it right and left or wrong and correct? At least that is my first impression after scanning your code.

Ilias

> On Dec 9, 2015, at 3:06 PM, Developer via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> It’s high time the STL admitted some kind of disjoint union type, at the very least because it’s such a minor addition it seems a shame to leave it out. Whatever feelings one may have about `throws`, the lack of standardizing on a datatype representing choice has caused the community to get creative and create many disjoint implementation of the same concept over and over and over again. To that end, I propose the STL ship with an Either type; We at TypeLift have already got our own we’d like to model it on (https://github.com/typelift/Swiftx/blob/master/Swiftx/Either.swift#L16).
>
>
> ~Robert Widmann (CodaFi)
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


(Robert Widmann) #11

How would you write `map` for an unbiased Either. You have to pick a side!

Our implementation happens to be the one standardized on by Scala, Haskell, ML, (and to a limited extent) F#. For a less arbitrary reason, the use of "Right as Correct" is because Either, in all it’s Bifunctor-ial ways, has to admit two ways to map “across” itself. To paraphrase the words of a friend "There are lots of things in computer science we can leftMap”. In Haskell, such a thing is represented by the Functor typeclass, and due to the way type application works in that language, the convention has been to map over the rightmost side. But this isn’t Haskell, so our reasons can get even more theoretical than that (if you really want to get into what it looks like when you implement Covariant mapping down the left side of a common Bifunctor like Either, Cats has already had a thorough discussion on the subject: https://github.com/non/cats/issues/189).

···

On Dec 9, 2015, at 6:44 PM, Ilias Karim <ilias.karim@gmail.com> wrote:

I’m sorry, I misunderstood. I guess an enum would be the appropriate choice, instead.

As far as left/right goes, the decision to have left or right be the “correct” value is entirely arbitrary and should be left up to the developer. It should be a convention at best.

Ilias

On Dec 9, 2015, at 3:43 PM, Dave DeLong <delong@apple.com <mailto:delong@apple.com>> wrote:

With a tuple, you have to do “(left: T?, right: U?)”, whereas with an Either you are guaranteed to always have one or other other; never both and never neither. That is not guaranteed with the tuple.

Dave

On Dec 9, 2015, at 4:41 PM, Ilias Karim via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

What are the advantage over using a tuple? One great feature about tuples is being able to name parameters so you can dispel ambiguity.

On Dec 9, 2015, at 3:35 PM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

The idea of using Left/Right is to remain agnostic to what sorts of things users might want to put in. It's feasible a user might want Either<Int, String>, not just Either<ErrorType, T>.

While I'm not sure Left & Right are the best choices, I don't think it's particularly worrisome when it comes to errors, as the general type-safety of the language will prevent users from mixing up success & error cases.

Jacob

On Wed, Dec 9, 2015 at 3:32 PM, Ilias Karim via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hi Robert,

I agree with your recommendation of a generic Either type.

However, I find your use of “Right” as the “Correct” value (whatever that means) of an instance of an Either type a little perplexing. While clever, it is exactly the kind of convention that easily leads to misunderstandings about the nature of the type itself ie. is it right and left or wrong and correct? At least that is my first impression after scanning your code.

Ilias

> On Dec 9, 2015, at 3:06 PM, Developer via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> It’s high time the STL admitted some kind of disjoint union type, at the very least because it’s such a minor addition it seems a shame to leave it out. Whatever feelings one may have about `throws`, the lack of standardizing on a datatype representing choice has caused the community to get creative and create many disjoint implementation of the same concept over and over and over again. To that end, I propose the STL ship with an Either type; We at TypeLift have already got our own we’d like to model it on (https://github.com/typelift/Swiftx/blob/master/Swiftx/Either.swift#L16).
>
>
> ~Robert Widmann (CodaFi)
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

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

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


(Matthew Johnson) #12

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?

I’m glad to see you holding off until these related design issues are sorted out.

Can you elaborate on what you mean by a corresponding Result<> type? I don’t follow the generic argument brackets without any arguments.

When it comes back up and assuming we have typed throws I would like to see support for multiple error types. I think it could be accomplished via an anonymous compiler generated sum type or something similar to that.


(Dave Abrahams) #13

Friends,

The STL <https://en.wikipedia.org/wiki/Standard_Template_Library> is a hugely influential and important effort, but it is not the Swift standard library. We don't want to be seen as either co-opting the name or taking credit for its design, nor do we want to sell short the unique strengths of Swift's own standard library by letting it be confused with that other body of work. My humble request is that, if we want to use a short name to refer to the Swift standard library, we choose a different one. "Stdlib" seems workable and precedented in our source directory layout, for example.

Thanks,
-Dave

···

On Dec 9, 2015, at 3:06 PM, Developer via swift-evolution <swift-evolution@swift.org> wrote:

It’s high time the STL admitted some kind of disjoint union type…


(Jacob Bandes-Storch) #14

Sorry, I'm bad at this proofreading thing. The fourth case is (A, B).

Jacob Bandes-Storch

···

On Wed, Dec 9, 2015 at 3:42 PM, Developer <devteam.codafi@gmail.com> wrote:

A tuple is a product, we want a sum here. A tuple says “I know I have 2
things”, a sum says “I know one or the other of these things is here but
not both” without the need to unwrap both halves just to check. Past a
certain point, you’re writing Either code over and over again without
realizing it.

On Dec 9, 2015, at 6:41 PM, Ilias Karim <ilias.karim@gmail.com> wrote:

What are the advantage over using a tuple? One great feature about tuples
is being able to name parameters so you can dispel ambiguity.

On Dec 9, 2015, at 3:35 PM, Jacob Bandes-Storch <jtbandes@gmail.com> > wrote:

The idea of using Left/Right is to remain agnostic to what sorts of things
users might want to put in. It's feasible a user might want Either<Int,
>, not just Either<ErrorType, T>.

While I'm not sure Left & Right are the best choices, I don't think it's
particularly worrisome when it comes to errors, as the general type-safety
of the language will prevent users from mixing up success & error cases.

Jacob

On Wed, Dec 9, 2015 at 3:32 PM, Ilias Karim via swift-evolution < > swift-evolution@swift.org> wrote:

Hi Robert,

I agree with your recommendation of a generic Either type.

However, I find your use of “Right” as the “Correct” value (whatever that
means) of an instance of an Either type a little perplexing. While clever,
it is exactly the kind of convention that easily leads to misunderstandings
about the nature of the type itself ie. is it right and left or wrong and
correct? At least that is my first impression after scanning your code.

Ilias

> On Dec 9, 2015, at 3:06 PM, Developer via swift-evolution < >> swift-evolution@swift.org> wrote:
>
> It’s high time the STL admitted some kind of disjoint union type, at
the very least because it’s such a minor addition it seems a shame to leave
it out. Whatever feelings one may have about `throws`, the lack of
standardizing on a datatype representing choice has caused the community to
get creative and create many disjoint implementation of the same concept
over and over and over again. To that end, I propose the STL ship with an
Either type; We at TypeLift have already got our own we’d like to model it
on (
https://github.com/typelift/Swiftx/blob/master/Swiftx/Either.swift#L16).
>
>
> ~Robert Widmann (CodaFi)
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


(Jacob Bandes-Storch) #15

Is there not precedent for having both "mapLeft<T>(f: L -> T) -> Either<T,

" and "mapRight<T>(f: R -> T) -> Either<L, T>" ?

Jacob Bandes-Storch

···

On Wed, Dec 9, 2015 at 3:49 PM, Developer <devteam.codafi@gmail.com> wrote:

How would you write `map` for an unbiased Either. You have to pick a side!

Our implementation happens to be the one standardized on by Scala,
Haskell, ML, (and to a limited extent) F#. For a less arbitrary reason,
the use of "Right as Correct" is because Either, in all it’s Bifunctor-ial
ways, has to admit two ways to map “across” itself. To paraphrase the
words of a friend "There are lots of things in computer science we can
leftMap”. In Haskell, such a thing is represented by the Functor
typeclass, and due to the way type application works in that language, the
convention has been to map over the rightmost side. But this isn’t
Haskell, so our reasons can get even more theoretical than that (if you
really want to get into what it looks like when you implement Covariant
mapping down the left side of a common Bifunctor like Either, Cats has
already had a thorough discussion on the subject:
https://github.com/non/cats/issues/189).

On Dec 9, 2015, at 6:44 PM, Ilias Karim <ilias.karim@gmail.com> wrote:

I’m sorry, I misunderstood. I guess an enum would be the appropriate
choice, instead.

As far as left/right goes, the decision to have left or right be the
“correct” value is entirely arbitrary and should be left up to the
developer. It should be a convention at best.

Ilias

On Dec 9, 2015, at 3:43 PM, Dave DeLong <delong@apple.com> wrote:

With a tuple, you have to do “(left: T?, right: U?)”, whereas with an
Either you are guaranteed to always have one or other other; never both and
never neither. That is not guaranteed with the tuple.

Dave

On Dec 9, 2015, at 4:41 PM, Ilias Karim via swift-evolution < > swift-evolution@swift.org> wrote:

What are the advantage over using a tuple? One great feature about tuples
is being able to name parameters so you can dispel ambiguity.

On Dec 9, 2015, at 3:35 PM, Jacob Bandes-Storch <jtbandes@gmail.com> > wrote:

The idea of using Left/Right is to remain agnostic to what sorts of things
users might want to put in. It's feasible a user might want Either<Int,
>, not just Either<ErrorType, T>.

While I'm not sure Left & Right are the best choices, I don't think it's
particularly worrisome when it comes to errors, as the general type-safety
of the language will prevent users from mixing up success & error cases.

Jacob

On Wed, Dec 9, 2015 at 3:32 PM, Ilias Karim via swift-evolution < > swift-evolution@swift.org> wrote:

Hi Robert,

I agree with your recommendation of a generic Either type.

However, I find your use of “Right” as the “Correct” value (whatever that
means) of an instance of an Either type a little perplexing. While clever,
it is exactly the kind of convention that easily leads to misunderstandings
about the nature of the type itself ie. is it right and left or wrong and
correct? At least that is my first impression after scanning your code.

Ilias

> On Dec 9, 2015, at 3:06 PM, Developer via swift-evolution < >> swift-evolution@swift.org> wrote:
>
> It’s high time the STL admitted some kind of disjoint union type, at
the very least because it’s such a minor addition it seems a shame to leave
it out. Whatever feelings one may have about `throws`, the lack of
standardizing on a datatype representing choice has caused the community to
get creative and create many disjoint implementation of the same concept
over and over and over again. To that end, I propose the STL ship with an
Either type; We at TypeLift have already got our own we’d like to model it
on (
https://github.com/typelift/Swiftx/blob/master/Swiftx/Either.swift#L16).
>
>
> ~Robert Widmann (CodaFi)
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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

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


(Robert Widmann) #16

There is! That’s what the Bifunctor typeclass is for. But if you had to pick just one of them to implement some Functor constraint - some canonical `map` function, would you pick the side that you filled with Errors, or the side that you filled with Values?

···

On Dec 9, 2015, at 6:52 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Is there not precedent for having both "mapLeft<T>(f: L -> T) -> Either<T, R>" and "mapRight<T>(f: R -> T) -> Either<L, T>" ?

Jacob Bandes-Storch

On Wed, Dec 9, 2015 at 3:49 PM, Developer <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:
How would you write `map` for an unbiased Either. You have to pick a side!

Our implementation happens to be the one standardized on by Scala, Haskell, ML, (and to a limited extent) F#. For a less arbitrary reason, the use of "Right as Correct" is because Either, in all it’s Bifunctor-ial ways, has to admit two ways to map “across” itself. To paraphrase the words of a friend "There are lots of things in computer science we can leftMap”. In Haskell, such a thing is represented by the Functor typeclass, and due to the way type application works in that language, the convention has been to map over the rightmost side. But this isn’t Haskell, so our reasons can get even more theoretical than that (if you really want to get into what it looks like when you implement Covariant mapping down the left side of a common Bifunctor like Either, Cats has already had a thorough discussion on the subject: https://github.com/non/cats/issues/189).

On Dec 9, 2015, at 6:44 PM, Ilias Karim <ilias.karim@gmail.com <mailto:ilias.karim@gmail.com>> wrote:

I’m sorry, I misunderstood. I guess an enum would be the appropriate choice, instead.

As far as left/right goes, the decision to have left or right be the “correct” value is entirely arbitrary and should be left up to the developer. It should be a convention at best.

Ilias

On Dec 9, 2015, at 3:43 PM, Dave DeLong <delong@apple.com <mailto:delong@apple.com>> wrote:

With a tuple, you have to do “(left: T?, right: U?)”, whereas with an Either you are guaranteed to always have one or other other; never both and never neither. That is not guaranteed with the tuple.

Dave

On Dec 9, 2015, at 4:41 PM, Ilias Karim via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

What are the advantage over using a tuple? One great feature about tuples is being able to name parameters so you can dispel ambiguity.

On Dec 9, 2015, at 3:35 PM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

The idea of using Left/Right is to remain agnostic to what sorts of things users might want to put in. It's feasible a user might want Either<Int, String>, not just Either<ErrorType, T>.

While I'm not sure Left & Right are the best choices, I don't think it's particularly worrisome when it comes to errors, as the general type-safety of the language will prevent users from mixing up success & error cases.

Jacob

On Wed, Dec 9, 2015 at 3:32 PM, Ilias Karim via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hi Robert,

I agree with your recommendation of a generic Either type.

However, I find your use of “Right” as the “Correct” value (whatever that means) of an instance of an Either type a little perplexing. While clever, it is exactly the kind of convention that easily leads to misunderstandings about the nature of the type itself ie. is it right and left or wrong and correct? At least that is my first impression after scanning your code.

Ilias

> On Dec 9, 2015, at 3:06 PM, Developer via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> It’s high time the STL admitted some kind of disjoint union type, at the very least because it’s such a minor addition it seems a shame to leave it out. Whatever feelings one may have about `throws`, the lack of standardizing on a datatype representing choice has caused the community to get creative and create many disjoint implementation of the same concept over and over and over again. To that end, I propose the STL ship with an Either type; We at TypeLift have already got our own we’d like to model it on (https://github.com/typelift/Swiftx/blob/master/Swiftx/Either.swift#L16).
>
>
> ~Robert Widmann (CodaFi)
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

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

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


(John McCall) #17

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?

I’m glad to see you holding off until these related design issues are sorted out.

Can you elaborate on what you mean by a corresponding Result<> type? I don’t follow the generic argument brackets without any arguments.

I was being intentionally vague about what the generic arguments to Result might be.

Evaluating a Swift expression always either yields a T or throws an E (or fails to terminate at all, but from a static perspective, we can ignore this). One purpose of Result is to allow the abstract result of that evaluation to be captured in a single value. It makes sense for Result to be parameterized by T, and possibly also by E.

Swift currently does not allow E to be constrained more precisely than just ErrorType. In this world, it makes sense to just be able to write Result<T>.

The point of typed “throws” is to allow E to be more constrained. In the simplest case, E might be one specific type; it might then make sense to be able to write Result<T, E>. However, there are more complex cases. For example, it might be possible to say (Java-like) that a function can throw any one of a set of different error types; would this have to be expressed as Result<T, E1, E2, E2, …>? That’s a tough fit for the generics system, especially since the error types are logically a set, not a sequence. Now, you could try to disallow this by saying that functions have to pick a single type that they can throw (e.g. ErrorType); but this doesn’t actually solve the problem, because expressions can contain multiple throw sites with different error types, so now you’ve got a set again. Again, you can force that back to the greatest common type (which will generally be ErrorType), but now Result loses information that normal type-checking would have preserved. So it’s a challenge.

When it comes back up and assuming we have typed throws I would like to see support for multiple error types. I think it could be accomplished via an anonymous compiler generated sum type or something similar to that.

Structural sum types (as opposed to nominal sum types like Either which are explicitly formed and broken down) are a massive complication for type systems.

John.

···

On Dec 9, 2015, at 6:43 PM, Matthew Johnson <matthew@anandabits.com> wrote:


(Thorsten Seitz) #18

The point of typed “throws” is to allow E to be more constrained. In the simplest case, E might be one specific type; it might then make sense to be able to write Result<T, E>. However, there are more complex cases. For example, it might be possible to say (Java-like) that a function can throw any one of a set of different error types; would this have to be expressed as Result<T, E1, E2, E2, …>? That’s a tough fit for the generics system, especially since the error types are logically a set, not a sequence.

You could just write Result<T, E1 | E2 | E3> where "|" is the type union operator if we had union types as in Ceylon (see http://ceylon-lang.org/documentation/tour/types/).
I’ve mentioned them once or twice on this list already and I do think they are really really powerful and useful while staying totally intuitive!

Now, you could try to disallow this by saying that functions have to pick a single type that they can throw (e.g. ErrorType); but this doesn’t actually solve the problem, because expressions can contain multiple throw sites with different error types, so now you’ve got a set again. Again, you can force that back to the greatest common type (which will generally be ErrorType), but now Result loses information that normal type-checking would have preserved. So it’s a challenge.

With union types no information is lost. I was really surprised how well they worked out in Ceylon (and I think the Ceylon guys were themselves pleasantly surprised, too).

-Thorsten

···

When it comes back up and assuming we have typed throws I would like to see support for multiple error types. I think it could be accomplished via an anonymous compiler generated sum type or something similar to that.

Structural sum types (as opposed to nominal sum types like Either which are explicitly formed and broken down) are a massive complication for type systems.

John.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jacob Bandes-Storch) #19

How about the Swift Standard Library (SSL)? :wink:

···

On Mon, Dec 14, 2015 at 1:06 AM, Dave Abrahams via swift-evolution < swift-evolution@swift.org> wrote:

On Dec 9, 2015, at 3:06 PM, Developer via swift-evolution < > swift-evolution@swift.org> wrote:

It’s high time the STL admitted some kind of disjoint union type…

Friends,

The STL <https://en.wikipedia.org/wiki/Standard_Template_Library> is a
hugely influential and important effort, but it is not the Swift standard
library. We don't want to be seen as either co-opting the name or taking
credit for its design, nor do we want to sell short the unique strengths of
Swift's own standard library by letting it be confused with that other body
of work. My humble request is that, if we want to use a short name to
refer to the Swift standard library, we choose a different one. "Stdlib"
seems workable and precedented in our source directory layout, for example.

Thanks,
-Dave

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


(TJ Usiyan) #20

I hope that we can get both Either and Result into the standard lib. A
great situation might be if Result were some sort of newtype declaration of
Either.

···

On Thu, Dec 10, 2015 at 5:25 AM, Developer via swift-evolution < swift-evolution@swift.org> wrote:

There is! That’s what the Bifunctor typeclass is for. But if you had to
pick just one of them to implement some Functor constraint - some canonical
`map` function, would you pick the side that you filled with Errors, or the
side that you filled with Values?

On Dec 9, 2015, at 6:52 PM, Jacob Bandes-Storch <jtbandes@gmail.com> > wrote:

Is there not precedent for having both "mapLeft<T>(f: L -> T) -> Either<T,
>" and "mapRight<T>(f: R -> T) -> Either<L, T>" ?

Jacob Bandes-Storch

On Wed, Dec 9, 2015 at 3:49 PM, Developer <devteam.codafi@gmail.com> > wrote:

How would you write `map` for an unbiased Either. You have to pick a
side!

Our implementation happens to be the one standardized on by Scala,
Haskell, ML, (and to a limited extent) F#. For a less arbitrary reason,
the use of "Right as Correct" is because Either, in all it’s Bifunctor-ial
ways, has to admit two ways to map “across” itself. To paraphrase the
words of a friend "There are lots of things in computer science we can
leftMap”. In Haskell, such a thing is represented by the Functor
typeclass, and due to the way type application works in that language, the
convention has been to map over the rightmost side. But this isn’t
Haskell, so our reasons can get even more theoretical than that (if you
really want to get into what it looks like when you implement Covariant
mapping down the left side of a common Bifunctor like Either, Cats has
already had a thorough discussion on the subject:
https://github.com/non/cats/issues/189).

On Dec 9, 2015, at 6:44 PM, Ilias Karim <ilias.karim@gmail.com> wrote:

I’m sorry, I misunderstood. I guess an enum would be the appropriate
choice, instead.

As far as left/right goes, the decision to have left or right be the
“correct” value is entirely arbitrary and should be left up to the
developer. It should be a convention at best.

Ilias

On Dec 9, 2015, at 3:43 PM, Dave DeLong <delong@apple.com> wrote:

With a tuple, you have to do “(left: T?, right: U?)”, whereas with an
Either you are guaranteed to always have one or other other; never both and
never neither. That is not guaranteed with the tuple.

Dave

On Dec 9, 2015, at 4:41 PM, Ilias Karim via swift-evolution < >> swift-evolution@swift.org> wrote:

What are the advantage over using a tuple? One great feature about tuples
is being able to name parameters so you can dispel ambiguity.

On Dec 9, 2015, at 3:35 PM, Jacob Bandes-Storch <jtbandes@gmail.com> >> wrote:

The idea of using Left/Right is to remain agnostic to what sorts of
things users might want to put in. It's feasible a user might want
Either<Int, String>, not just Either<ErrorType, T>.

While I'm not sure Left & Right are the best choices, I don't think it's
particularly worrisome when it comes to errors, as the general type-safety
of the language will prevent users from mixing up success & error cases.

Jacob

On Wed, Dec 9, 2015 at 3:32 PM, Ilias Karim via swift-evolution < >> swift-evolution@swift.org> wrote:

Hi Robert,

I agree with your recommendation of a generic Either type.

However, I find your use of “Right” as the “Correct” value (whatever
that means) of an instance of an Either type a little perplexing. While
clever, it is exactly the kind of convention that easily leads to
misunderstandings about the nature of the type itself ie. is it right and
left or wrong and correct? At least that is my first impression after
scanning your code.

Ilias

> On Dec 9, 2015, at 3:06 PM, Developer via swift-evolution < >>> swift-evolution@swift.org> wrote:
>
> It’s high time the STL admitted some kind of disjoint union type, at
the very least because it’s such a minor addition it seems a shame to leave
it out. Whatever feelings one may have about `throws`, the lack of
standardizing on a datatype representing choice has caused the community to
get creative and create many disjoint implementation of the same concept
over and over and over again. To that end, I propose the STL ship with an
Either type; We at TypeLift have already got our own we’d like to model it
on (
https://github.com/typelift/Swiftx/blob/master/Swiftx/Either.swift#L16).
>
>
> ~Robert Widmann (CodaFi)
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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

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

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