<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="">On Jun 6, 2016, at 2:49 PM, Michael Peternell &lt;<a href="mailto:michael.peternell@gmx.at" class="">michael.peternell@gmx.at</a>&gt; wrote:<br class=""><div><blockquote type="cite" class=""><br class="Apple-interchange-newline"><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">That's really hard to answer in the general case. I think real proposals should contain concrete, realistic examples that show the benefit of the proposal. It's really hard to argue against a proposal if there is no such example. User feedback from a sheet is one of the few examples where asynchronous programming makes sense: But I cannot see how a `@required` annotation would be useful in that setting.</span></div></blockquote></div><br class=""><div class="">Quick-n-dirty example, written in Mail. How would you make this synchronous?</div><div class=""><br class=""></div><div class=""><div class="">import Foundation</div><div class=""><br class=""></div><div class="">enum Result&lt;T&gt; {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>case success(T)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>case error(ErrorType)</div><div class="">}</div><div class=""><br class=""></div><div class="">enum MyError: ErrorType {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>case unknownError</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>case corruptData</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>case badStatusCode(Int)</div><div class="">}</div><div class=""><br class=""></div><div class="">struct SomeThing {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>init?(data: NSData) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>...</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class="">}</div><div class=""><br class=""></div><div class="">func getSomethingFromTheNetwork(url: NSURL, completionHandler: (Result&lt;SomeThing&gt;) -&gt; ()) {<span class="Apple-tab-span" style="white-space:pre">        </span></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let task = NSURLSession.sharedSession().dataTaskWithURL(url) { data, response, error in</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>if let error = error {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>completionHandler(.error(error))</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>return</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>if let httpResponse = response as? NSHTTPURLResponse {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>let statusCode = httpResponse.statusCode</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span></div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>if statusCode &lt; 200 || statusCode &gt;= 300 {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                </span>completionHandler(.error(MyError.badStatusCode(statusCode)))</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                </span>return</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span></div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>guard let data = data else {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>completionHandler(.error(MyError.unknownError))</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>return</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>guard let something = SomeThing(data: data) else {</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                        </span>completionHandler(.error(MyError.corruptData))</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>return</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>completionHandler(.success(something))</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>task.resume()</div><div class="">}</div></div><div class=""><br class=""></div><div class="">(disclaimer: yes, we’d probably have to improve the API for NSURLSession a bit here for @required to be useful.)</div><div class=""><br class=""></div><div class="">How would you make this synchronous:</div><div class=""><br class=""></div><div class="">func getSomethingFromAnotherTask(completionHandler: (Result&lt;SomeThing&gt;) -&gt; ()) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let message = ...</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>xpc_send_message_with_reply(self.connection, message, self.dispatchQueue) { reply in</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>do {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>let something = try self.turnReplyIntoSomethingSomehow(reply)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span></div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>completionHandler(.success(something))</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>} catch {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>completionHandler(.error(error))</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class="">}</div><div class=""><br class=""></div><div class="">Or this:</div><div class=""><br class=""></div><div class="">func doSomethingThatNeedsUserInput(completionHandler: (Bool) -&gt; ()) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let alert = NSAlert()</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>alert.messageText = “Should we continue?”</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>alert.addButtonWithTitle(“Continue”)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>alert.addButtonWithTitle(“Cancel”)</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>alert.beginSheetModalForWindow(someWindow) { response in</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>if response == NSAlertFirstButtonReturn {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>completionHandler(true)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>// uh oh, I forgot to test for other conditions, and now the completion handler won’t be called if the user clicked “Cancel”.</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>//&nbsp;Too bad the compiler couldn’t warn me about it.</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class="">}</div><div class=""><br class=""></div><div class="">There are some tasks which synchronous programming is simply not well-suited for.</div><div class=""><br class=""></div><div class="">Charles</div><div class=""><br class=""></div></body></html>