> Am 05.06.2016 um 11:37 schrieb Charles Srstka via swift-evolution 
> <[email protected]>:
> 
> MOTIVATION:
> 
> As per the current situation, there is a pitfall when writing asynchronous 
> APIs that does not occur when writing synchronous APIs. Consider the 
> following synchronous API:
> 
> func doSomething() -> SomeEnum {
>       if aCondition {
>               if bCondition {
>                       return .Foo
>               } else {
>                       return .Bar
>               }
>       } else {
>               if cCondition {
>                       return .Baz
>               }
>       }
> }
> 

That's a good design...

> The compiler will give an error here, since if both aCondition and cCondition 
> are false, the function will not return anything.
> 
> However, consider the equivalent async API:
> 
> func doSomething(completionHandler: (SomeEnum) -> ()) {
>       dispatch_async(someQueue) {
>               if aCondition {
>                       if bCondition {
>                               completionHandler(.Foo)
>                       } else {
>                               completionHandler(.Bar)
>                       }
>               } else {
>                       if cCondition {
>                               completionHandler(.Baz)
>                       }
>               }
>       }
> }

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)

-Michael

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

Reply via email to