Sent from my iPad

> On Jun 5, 2016, at 5:02 AM, Patrick Pijnappel via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> This has actually been proposed before, see SE-0073: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0073-noescape-once.md

Actually that proposal was for noescape closures and this suggestion is for 
escaping closures.  I don't think the compiler can verify this for noescape 
closures.  If it is possible it would be far more complicated.

> 
> 
>> On Sun, Jun 5, 2016 at 11:37 AM, Charles Srstka via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 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
>>                 }
>>         }
>> }
>> 
>> 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)
>>                         }
>>                 }
>>         }
>> }
>> 
>> Whoops, now the function can return without ever firing its completion 
>> handler, and the problem might not be discovered until runtime (and, 
>> depending on the complexity of the function, may be hard to find).
>> 
>> PROPOSED SOLUTION:
>> 
>> Add a @required attribute that can be applied to closure arguments. This 
>> attribute simply states that the given closure will always be eventually 
>> called, and the compiler can enforce this.
>> 
>> DETAILED DESIGN:
>> 
>> - The @required attribute states in our API contract that a given closure 
>> *must* be called at some point after the function is called.
>> 
>> - Standard API calls like dispatch_async that contractually promise to 
>> execute a closure or block get @required added to their signatures.
>> 
>> - When the compiler sees a @required closure in a function declaration, it 
>> checks to make sure that every execution path either calls the closure at 
>> some point, or sends a @required closure to another API that eventually ends 
>> up calling the closure.
>> 
>> - If there’s a way for a @required closure not to be called, the compiler 
>> emits an error letting the developer know about the bug in his/her code.
>> 
>> IMPACT ON EXISTING CODE:
>> 
>> None. This is purely additive.
>> 
>> ALTERNATIVES CONSIDERED:
>> 
>> I got nothin’.
>> 
>> Charles
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to