Here we go again... -1 On Fri, 17 Feb 2017 at 23:52 Matthew Johnson via swift-evolution < swift-evolution@swift.org> wrote:
> On Feb 17, 2017, at 3:45 PM, Joe Groff via swift-evolution < > swift-evolution@swift.org> wrote: > > > On Feb 17, 2017, at 11:03 AM, Adrian Zubarev via swift-evolution < > swift-evolution@swift.org> wrote: > > I suggest we need to find a way to shorten the list of the possible error > types with a the help of typeallias > > extension MyError1: Error { ... } > extension MyError2: Error { ... } > extension MyError3: Error { ... } > > typealias MyErrors = MyError1 | MyError2 | MyError3 > > func foo() throws(MyErrors) -> MyResult > func bar<T : Error>(_: () throws(T) -> Void) rethrows(MyErrors, T) -> MyResult > > Do you actually need that? Experience in other languages like Rust and > Haskell that use Result-based error propagation suggests that a single > error type is adequate, and beneficial in many ways. If nothing else, you > could `Either` your way to multiple errors if you really needed to. > > IMO, if we accept a single error type per function, there could be a > simpler model for this. We could say that the `throws` type is a generic > parameter of all function types, and it defaults to the uninhabited `Never` > type for functions that don't throw. > > () -> () == () throws Never -> () > () throws -> () == () throws Error -> () > > In this model, you'd get many benefits: > > - `rethrows` could become first-class, reducing down to just polymorphic > `throws`: > > func foo(_: () throws -> ()) rethrows // Swift 3 > func foo<T: Error>(_: () throws T -> ()) throws T // Swift X > func foo<T: Error>(_: () throws T -> ()) throws Either<MyErrors, T> > > - Protocols could abstract over error handling; for instance, we could > support throwing sequences: > > protocol IteratorProtocol { > associatedtype Element > associatedtype Error: Swift.Error = Never > > mutating func next() throws Error -> Element? > } > > Separate of the type system model, the type *checking* model also deserves > thorough consideration. Propagating the effects of possibly multiple error > types propagating within a `do` block is much trickier than doing so as a > single "throws" or not bit, especially if you want to be able to use type > context in `catch` patterns or to implicitly propagate a narrower `throws` > type out of the enclosing function. > > > I agree with all of this. The correct way to handle functions that throw > multiple error types is with a discriminated union (enum) or an > existential. > > If we make enums easier to work with (see my manifesto on generalized > enums and value subtyping), we also make it easier to address the use case > of functions that need to throw several different error types. That is the > more general and useful way to address this use case. > > > -Joe > _______________________________________________ > 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