<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Dec 13, 2017, at 10:20 AM, Stephen Celis via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><blockquote type="cite" class="">On Dec 11, 2017, at 1:08 PM, Matthew Johnson via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class="">It’s worth mentioning that the problem this thread is discussing can be generalized to idioms / applicative. The specific case here is for Optional but many other types could benefit from an elegant syntactic solution to this problem. It might be worth exploring a more general solution. Here’s a link to how this is handled in Idris: <a href="http://docs.idris-lang.org/en/latest/tutorial/interfaces.html#idiom-brackets" class="">http://docs.idris-lang.org/en/latest/tutorial/interfaces.html#idiom-brackets</a>.<br class=""><br class="">Matthew<br class=""></blockquote><br class="">Just want to +1 a more general, less "Optional"-specific solution. You can do a ton of interesting things with applicative structure.<br class=""><br class=""></div></div></blockquote><div><br class=""></div><div>Chris L had a beautiful solution for an "Unwrappable" protocol that allowed all of the optional sugar to be extended to any type that had a biased `Wrapped` item, allowing it to be used with `Either`, `Wrapped`, etc as well as form the basis for `Optional` itself.</div><div><br class=""></div><div><pre style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 0px; word-wrap: normal; padding: 16px; overflow: auto; line-height: 1.45; background-color: rgb(246, 248, 250); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; color: rgb(36, 41, 46);" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">protocol</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(111, 66, 193);">Unwrappable</span> {
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">associatedtype</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">Element</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(111, 66, 193);">unwrap</span>() <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">-></span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">Element</span><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">?</span>
}</pre></div><div><br class=""></div><div>I have a proposal around somewhere.(1)</div><div><br class=""></div><div>-- E</div><div>(1) But then again, I have a lot of those</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div class="">Failures from "Optional" and "throws" operate sequentially and halt immediately: the first "nil" or "throw" encountered prevents all work chained from it[1]. Another upcoming sequential operation that's worth thinking about in this discussion: "async"/"await".<br class=""><br class="">Applicative structures throw away that sequential constraint. Let's consider some fun things that happen when we take it away in a couple of the examples above.<br class=""><br class="">If "throws" were applicative, you could accumulate a bunch of errors at once.<br class=""><br class=""> do { <br class=""> // made-up syntax<br class=""> let user = User(|name: try validate(name: name), email: try validate(email: email)|)<br class=""> } catch {<br class=""> print(error) // .manyErrors(["name is too short", "email is invalid"])<br class=""> }<br class=""><br class="">Currently, the above would halt on the first error.<br class=""><br class="">If "async"/"await" were applicative, you could fire off a bunch of asynchronous requests in parallel.<br class=""><br class=""> let homepageData = HomepageData(|await fetchCurrentUser(), await fetchProducts()|)<br class=""><br class="">In the proposed version of "async"/"await", the above would block on "fetchCurrentUser()" and only call "fetchProducts()" after the response.<br class=""><br class="">"Optional" would get to use that same sugar! An example from the original email:<br class=""><br class=""> getPostageEstimate(|source: john.address, destination: alice.address, weight 2.0|)<br class=""><br class=""><br class="">--<br class="">[1]: "Optional" and "throws" are monadic structures and "flatMap" is the abstraction of this sequential operation.<br class=""><br class=""><br class="">Stephen<br class=""><br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></div></blockquote></div><br class=""></body></html>