<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=""><div class="">Like you mentioned, the Swift team has made it very clear that concurrency is out of scope for Swift 3, and we probably won’t see it until at least Swift 4 at a bare minimum. &nbsp;That said, while your proposal is a <b class="">much</b> better alternative to the completion handler pyramids of doom we have today, I’ve personally never been a huge fan of Futures from an intuitiveness standpoint. &nbsp;I would much rather see the language adopt something more akin to C#’s Async-Await, where the compiler handles restructuring synchronous-looking code into something asynchronous and non-blocking.</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; line-height: normal;" class="">I guess in my perfect world, the following Swift 2 code:</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: 'Courier New'; color: rgb(187, 44, 162); min-height: 12px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span style="color: rgb(187, 44, 162);" class="">func</span> bar(completionHandler : (<span style="color: rgb(112, 61, 170);" class="">Int</span>) -&gt; <span style="color: rgb(112, 61, 170);" class="">Void</span>) -&gt; <span style="color: rgb(112, 61, 170);" class="">Void</span> {</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>dispatch_after( dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * <span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">1</span>), dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, <span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">0</span> ) ) {</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>completionHandler(<span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">42</span>)</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class="">}</font></div><div style="margin: 0px; font-size: 11px; line-height: normal; min-height: 12px;" class=""><font face="Menlo" class=""><br class=""></font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> barPlusBar(completionHandler : (<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span>) -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Void</span>) -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Void</span> {</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span>&nbsp;barResult = <span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">0</span></font></div><div style="margin: 0px; font-size: 11px; line-height: normal; min-height: 12px;" class=""><font face="Menlo" class=""><br class=""></font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>bar() { (<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> result) -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Void</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">in</span></font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">                </span></font><span style="font-family: Menlo;" class="">barResult</span><font face="Menlo" class="">&nbsp;+= result</font></div><div style="margin: 0px; font-size: 11px; line-height: normal; min-height: 12px;" class=""><font face="Menlo" class=""><br class=""></font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>bar() { (<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> result) -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Void</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">in</span></font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">                        </span></font><span style="font-family: Menlo;" class="">barResult</span><font face="Menlo" class="">&nbsp;+= result</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>completionHandler(&nbsp;</font><span style="font-family: Menlo;" class="">barResult</span><font face="Menlo" class="">&nbsp;)</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>}</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class="">}</font></div><div style="margin: 0px; font-size: 11px; line-height: normal; min-height: 12px;" class=""><font face="Menlo" class=""><br class=""></font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> foo() -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Void</span> {</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>barPlusBar() { (<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> result) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">in</span></font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>print( result )</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class="">}</font></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: 'Courier New'; min-height: 12px;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">would be replaced (and perhaps even become more optimizable) with:</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: 'Helvetica Neue'; min-height: 12px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span style="color: rgb(187, 44, 162);" class="">async func</span> bar() -&gt; <span style="color: rgb(112, 61, 170);" class="">Int</span> {</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>after( NSEC_PER_SEC * <span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">1 )</span></font></div><div style="margin: 0px; font-size: 11px; line-height: normal; color: rgb(187, 44, 162);" class=""><font face="Menlo" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span>return <span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">42</span></font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class="">}</font></div><div style="margin: 0px; font-size: 11px; line-height: normal; min-height: 12px;" class=""><font face="Menlo" class=""><br class=""></font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">async func</span> barPlusBar() -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span> {</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return </span>bar() + bar()</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class="">}</font></div><div style="margin: 0px; font-size: 11px; line-height: normal; min-height: 12px;" class=""><font face="Menlo" class=""><br class=""></font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> foo() -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Void</span> {</font></div><div style="margin: 0px; font-size: 11px; line-height: normal; color: rgb(187, 44, 162);" class=""><font face="Menlo" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span>async<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> {</span></font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>print( barPlusBar() )</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div><div style="margin: 0px; font-size: 11px; line-height: normal;" class=""><font face="Menlo" class="">}</font></div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Again, this is pretty much all moot right now as the Swift team has much bigger fish to fry, but it sure is nice to dream.</div><div class=""><br class=""></div><div class="">Dan</div><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 22, 2015, at 2:48 AM, Thomas Visser via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Hi all,<br class=""><br class="">Futures (aka Promises) are a well known concept that aid in writing asynchronous code. I’d love to have a Future type that comes with the language.<br class=""><br class="">The way I’d see this work is similar to how Optionals are currently implemented. There’d be a Future&lt;T&gt; type in the standard library, but most developers will choose not to use it directly. Instead, there are some new keywords and syntactic sugar that make it easy to work with the Future concept.<br class=""><br class="">There’d be a new ‘async’ keyword indicating that a type (including return type) is asynchronous:<br class=""><br class="">func blurImage(image: UIImage, radius: Int) -&gt; async UIImage {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>var blurredImage: async UIImage<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>dispatch_async(globalQueue) {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>blurredImage = // expensive blur operation<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>return blurredImage<br class="">}<br class=""><br class="">At the origin of an asynchronous value is something like GCD to actually execute the work on a different thread. (This is not the responsibility of the Future.)<br class=""><br class="">An async type should largely just work like its ‘regular’ synchronous counterpart. The compiler would be able to generate code for methods on that type (e.g. hasPrefix(_:) on an async string returns an async Bool) or methods (including operators) that take that type as a parameter (E.g. concatenating two async strings should be as easy as: string1 + string2).<br class=""><br class="">To unwrap a Future, i.e. getting its value, for cases that do not accept asynchronous values (e.g. UI updates), there’d be a new ‘when let’ statement with a control flow that is similar to the guard statement:<br class=""><br class="">when let image = blurImage(image) else {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>throw ImageBlurringFailed()<br class="">}<br class=""><br class="">imageView.image = image<br class=""><br class="">This is all very brief, but should give you an idea of my proposal. You can find more details in a blog post I wrote recently: <a href="http://www.thomasvisser.me/2015/11/26/async-swift/" class="">http://www.thomasvisser.me/2015/11/26/async-swift/</a>. This description is probably rather simplistic compared to the work needed to actually support something like this, but I hope it can serve as a starting point.<br class=""><br class="">Context:<br class="">- There is a proposal by Nadav Rotem from September 2015 that describes a lot of the foundational work that would have to be done before we can have a safe Future type: <a href="https://github.com/apple/swift/blob/5eaa3c43d069d5bd401e7879b43f6290823d180d/docs/proposals/Concurrency.rst" class="">https://github.com/apple/swift/blob/5eaa3c43d069d5bd401e7879b43f6290823d180d/docs/proposals/Concurrency.rst</a>. While I think a Future type could exist without language support for concurrency (e.g. using GCD directly, see <a href="https://github.com/Thomvis/BrightFutures" class="">https://github.com/Thomvis/BrightFutures</a>, full disclosure: I wrote that library), I agree it makes a lot of sense to only do it once it can be done in a safe way.<br class="">- There are other concepts that have to do with asynchronous programming such as channels/signals/observables (Rx) and goroutines. I think there’s a place &amp; audience for more than one of these concepts in Swift, but these efforts should of course be coordinated.<br class=""><br class="">I realize this is not in scope for Swift 3, but I’d love to get feedback from the community and hear how it can be incorporated in the discussion when concurrency will be on the agenda (for Swift 4 perhaps)?<br class=""><br class="">Best,<br class="">Thomas Visser<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>