On Jun 6, 2016, at 2:49 PM, Michael Peternell <michael.petern...@gmx.at> wrote:
> 
> 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.

Quick-n-dirty example, written in Mail. How would you make this synchronous?

import Foundation

enum Result<T> {
        case success(T)
        case error(ErrorType)
}

enum MyError: ErrorType {
        case unknownError
        case corruptData
        case badStatusCode(Int)
}

struct SomeThing {
        init?(data: NSData) {
                ...
        }
}

func getSomethingFromTheNetwork(url: NSURL, completionHandler: 
(Result<SomeThing>) -> ()) {     
        let task = NSURLSession.sharedSession().dataTaskWithURL(url) { data, 
response, error in
                if let error = error {
                        completionHandler(.error(error))
                        return
                }

                if let httpResponse = response as? NSHTTPURLResponse {
                        let statusCode = httpResponse.statusCode
                        
                        if statusCode < 200 || statusCode >= 300 {
                                
completionHandler(.error(MyError.badStatusCode(statusCode)))
                                return
                        }
                }
        
                guard let data = data else {
                        completionHandler(.error(MyError.unknownError))
                        return
                }

                guard let something = SomeThing(data: data) else {
                        completionHandler(.error(MyError.corruptData))
                        return
                }

                completionHandler(.success(something))
        }
        
        task.resume()
}

(disclaimer: yes, we’d probably have to improve the API for NSURLSession a bit 
here for @required to be useful.)

How would you make this synchronous:

func getSomethingFromAnotherTask(completionHandler: (Result<SomeThing>) -> ()) {
        let message = ...

        xpc_send_message_with_reply(self.connection, message, 
self.dispatchQueue) { reply in
                do {
                        let something = try 
self.turnReplyIntoSomethingSomehow(reply)
                
                        completionHandler(.success(something))
                } catch {
                        completionHandler(.error(error))
                }
        }
}

Or this:

func doSomethingThatNeedsUserInput(completionHandler: (Bool) -> ()) {
        let alert = NSAlert()

        alert.messageText = “Should we continue?”
        alert.addButtonWithTitle(“Continue”)
        alert.addButtonWithTitle(“Cancel”)

        alert.beginSheetModalForWindow(someWindow) { response in
                if response == NSAlertFirstButtonReturn {
                        completionHandler(true)
                }

                // uh oh, I forgot to test for other conditions, and now the 
completion handler won’t be called if the user clicked “Cancel”.
                // Too bad the compiler couldn’t warn me about it.
        }
}

There are some tasks which synchronous programming is simply not well-suited 
for.

Charles

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to