While I agree with Michael that nowadays, a lot of stuff that doesn't need to 
be, is done async, which leads to a giant thread pool per app and developers 
nowadays do not think of the cost of inter-thread communication (i.e. each 
dispatch_(a)sync has its cost, even though it's a light-weight thread), I agree 
with Charles that something like suggested does indeed help debugging issues 
with multi-thread apps.


> On Jun 5, 2016, at 7:59 PM, Charles Srstka via swift-evolution 
> <[email protected]> wrote:
> 
>> On Jun 5, 2016, at 10:28 AM, Michael Peternell <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> This is not a good design. If you want the completion handler to be called, 
>> you can rewrite the function to make this intent obvious:
>> 
>> func doSomethingAsync(completionHandler: (SomeEnum) -> ()) {
>>    dispatch_async(someQueue) {
>>        let result = doSomething()
>>        completionBlock(result)
>>    }
>> }
>> 
>> func doSomething() -> SomeEnum {
>>    if aCondition {
>>        if bCondition {
>>            return .Foo
>>        } else {
>>            return .Bar
>>        }
>>    } else {
>>        if cCondition {
>>            return .Baz
>>        }
>>    }
>> }
>> 
>> and this begs the question why the doSomethingAsync() function is needed at 
>> all.. Calling dispatch_async directly is probably more convenient and the 
>> abstraction of doSomething() probably not that useful.. (I know the example 
>> is overly simplistic, but I can apply the same reasoning to more complex 
>> scenarios just as easily too.)
>> 
>> IMHO, asynchronous programming is only a good thing when used in moderation. 
>> In most cases that I see, it just makes everything harder to reason about. 
>> For most applications, it's best to have one UI thread and one worker 
>> thread. This leads to code that is debuggable, testable and inspectable. For 
>> example, it wouldn't help a C compiler if it can use multiple threads to 
>> compile a file; usually you have much more files to compile than cores, so 
>> you can let `make` do the scheduling. Concurrency-management code and 
>> application code should never be mixed, as much as possible and practical. 
>> Asynchronous code violates this principle regularly.
>> 
>> assert(async programming == Goto 2.0)
> 
> Well, the example I gave *was* deliberately simplistic; there are many cases 
> where the code needs to call APIs which themselves are asynchronous. If the 
> purpose of doSomething() is to grab something from the network, and then do 
> something with it, then it’s going to be using async APIs under the hood if 
> you’re doing it the recommended way. Similarly, if the method grabs something 
> from another task using XPC, that’s asynchronous. Pop up a sheet to ask the 
> user for feedback before continuing? Asynchronous. NSUserScriptTask? 
> Asynchronous. Yeah, you can use a dispatch semaphore to hack these async APIs 
> into synchronous ones, but then you’re violating Apple’s recommendation about 
> never blocking dispatch queues.
> 
> Anyway, I don’t think asynchronous APIs are going away any time soon, and it 
> would be nice if it were easier to safely write them.
> 
> Charles
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to