Sent from my iPad
> On Jun 5, 2016, at 6:56 AM, Andrew Bennett <cac...@gmail.com> wrote: > > I like this. > > One of the suggestions on @noescape(once) was that it just becomes @once and > works with escaping closures too. It might be possible if compile time checks > verified that the closure isn't copied, and that it is called before being > deinit-ialized. Failing that I'm happy with a runtime circumstance in the > cases the compiler can't check. Yeah, maybe if it is only used asynchronously and never stored in a member or global it could be verified and that is a pretty common case. That would certainly be easier than the general case. I prefer @once over @required if the guarantee is single execution. If the guarantee is *at least once* obviously @once is not the right attribute, but I'm not convinced @required is either. Maybe @invoked. > > It would be great if @required took into the account the feedback from that > proposal and considered the synchronous case too. > > As an aside, you can get some of the guarantees you want like this: > > func doSomething(completionHandler: (SomeEnum) -> ()) { > dispatch_async(someQueue) { > let result: SomeEnum > // the compiler ensures 'result' is set > defer { completionHandler(result) } > > if aCondition { > if bCondition { > result = .Foo > } else { > result = .Bar > } > // the compiler ensures you do this, because it is 'let' > return > } > > if cCondition { > result = .Baz > } > } > } > >> On Sun, Jun 5, 2016 at 9:42 PM, Matthew Johnson via swift-evolution >> <swift-evolution@swift.org> wrote: >> >> >> 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 >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution