[swift-evolution] Pitch: @required attribute for closures

Charlie Monroe charlie at charliemonroe.net
Sun Jun 5 13:31:15 CDT 2016


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 <swift-evolution at swift.org> wrote:
> 
>> On Jun 5, 2016, at 10:28 AM, Michael Peternell <michael.peternell at gmx.at <mailto:michael.peternell at gmx.at>> 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
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160605/b4b5f41e/attachment.html>


More information about the swift-evolution mailing list