<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 15, 2016, at 6:39 AM, Yuta Koshizawa <<a href="mailto:koher@koherent.org" class="">koher@koherent.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">2016-03-15 2:23 GMT+09:00 Joe Groff <<a href="mailto:jgroff@apple.com" class="">jgroff@apple.com</a>>:<br class=""><blockquote type="cite" class=""><br class="">Yeah, we extensively discussed adding a Result type internally, but<br class="">ultimately couldn't justify it. The only real use case we could see in the<br class="">wild was for threading errors through CPS-inversion-style abstractions like<br class="">async promises, something we hope to provide proper language support for.<br class="">More generally, expressing effects as monadic values is a pretty awful<br class="">abstraction; aside from polluting the Internet with an endless deluge of<br class="">unhelpful tutorials, they also don't compose cleanly, they impose nesting<br class="">where is desired—you have to pick between Result<Async<T>> and<br class="">Async<Result<T>>, or build ResultT<AsyncT<Identity>><T> out of monad<br class="">transformers—and they don't do the natural thing when used with other<br class="">higher-order abstractions—if you're mapping a `throws` function over a<br class="">collection, you probably want to propagate that error like `rethrows` does,<br class="">not end up with a collection of Result<T>.<br class=""></blockquote><br class="">Yes, I know the pain of nested monads and I don't want to encourage<br class="">monadic error handling with awful nests.<br class=""><br class="">To tell the truth, I ultimately desire to unify `Optional`s, `throws`<br class="">and `Result`s.<br class=""><br class="">We have already had `Optional`s which can be used in a monadic way. To<br class="">prevent excessive monadic handling, I think we need Automatic<br class="">Propagation for `Optional`s.<br class=""><br class="">```<br class="">// Automatic Propagation for `Optional`s<br class="">let a: Int? = ...<br class="">let b: Int? = ...<br class=""><br class="">do {<br class=""> let sum: Int = (try a) + (try b)<br class=""> ...<br class="">} catch { // if `a` and/or `b` are `nil`<br class=""> ...<br class="">}<br class="">```<br class=""><br class="">Although "Error Handling Rational and Proposal" says `Optional`s<br class="">should be used for simple domain errors and are suitable for Manual<br class="">Propagation, I think Automatic Propagation is also useful for<br class="">`Optional`s. We get `nil` not only as errors but also as empty values.<br class="">Our codes are full of `Optional`s. Handling them manually costs a lot.<br class="">So I think it is good to have Automatic Propagation for `Optional`s.<br class=""><br class="">However it is confusing to mix `Optional`s and `throws` functions with<br class="">the same keyword `try`. So I think something like `typealias<br class="">Optional<T> = Result<T, NilError>`, which could be identical in a<br class="">binary form to current `Optional` with `struct NilError: ErrorType<br class="">{}`, and unified `throws` and `Result`s would be better. Then we would<br class="">have only `Result`s, but it could be used as `Optional`s and `throws`.<br class=""><br class="">Although `Result`s might make it possible to abuse monadic error<br class="">handling, problems of abuses are also true for other language<br class="">features: e.g. `(Float, Float)` as `Vector2` instead of `struct<br class="">Vector2 { ... }` for tuples. Even if we keep `Optional`s and `throws`<br class="">separated, `Optional`s can be handled monadically and we need to<br class="">encourage people how and when to use them to prevent abuses. I think<br class="">language features cannot prevent abuses, and it is a role of coding<br class="">guidelines.<br class=""><br class="">So I think it is good to unify `Optional`s, `throws` and `Result`s.<br class="">But because it seemed too radical, I proposed the part of it at first:<br class="">`throws -> Foo` as a syntactic sugar of `-> Result<Foo>`.<br class=""></div></div></blockquote><div><br class=""></div><div>I agree, it's nice to be able to open optionals and avoid direct monadic manipulations too. Optionals can be lifted and extracted from a `throws` body fairly easily already, much like a `Result`:</div><div><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><div>enum Nil: ErrorType { case Nil }</div><div>extension Optional {</div><div> func getOrThrow() throws -> Wrapped {</div><div> if let x = self { return x }</div><div> throw Nil.Nil </div><div> }</div><div>}</div><div>func doOrNil<T, U>(f: (T) throws -> U, x: T) -> U? {</div><div> do {</div><div> return try f(x)</div><div> } catch {</div><div> return nil</div><div> }</div><div>}</div></div></blockquote><div><br class=""></div><div>The latter is provided by the language as `try?` already. If we had typed `throws`, it would be nice to be able to express `throws Nil` more precisely, of course.</div><div><br class=""></div><div>-Joe</div><div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class="">I'd rather see us adopt an<br class="">extensible algebraic effects system, something like <a href="http://www.eff-lang.org" class="">http://www.eff-lang.org</a>,<br class="">which provides a framework for `throws`, `async` and other control flow<br class="">effects to be cleanly composed and abstracted over. I see `throws` as the<br class="">first seed of that.<br class=""></blockquote><br class="">Thank you for the information. Because I am not familiar with Eff, I<br class="">will check it. If it composes multiple abstractions well, it must be<br class="">great!<br class=""><br class="">-- Yuta<br class=""></div></div></blockquote></div><br class=""></body></html>