[swift-evolution] Guaranteed closure execution

Chris Lattner clattner at apple.com
Mon Feb 1 14:44:11 CST 2016


> On Jan 31, 2016, at 9:12 PM, Félix Cloutier <felixcca at yahoo.ca> wrote:
> 
> 
>> Le 31 janv. 2016 à 23:41:59, Chris Lattner <clattner at apple.com> a écrit :
>>> Rationale for some points:
>>> 
>>>> Only one closure parameter can be marked as @noescape(once) in a function signature.
>>> 
>>> 
>>> The attribute doesn't specify the order of execution of the closures, so it could have unintended consequences if closure B depends on closure A but closure B is called first. Given the typical use case (the @noescape(once) closure as a trailing closure), I don't think that it's worth it to invest a lot of effort into coming up with a model to decide (and enforce) which closure has to be called first and what to do if either closure throws or something.
>> 
>> I don’t see a reason to have this limitation.  Definitive initialization has to be able to generate conditional code for partially initialized cases anyway, e.g.:
>> 
>> var c : C
>> 
>> if … {
>>   c = C()
>> }
>> c = C()  // could be an initialization or an assignment.
>> use(c)
>> 
>> The caller side would just have to conservatively prove that the closure bodies initialized any values they touch before using them (or that they were initialized already at the call site).
> 
> I'm not sure I communicated the concern clearly. Here's an example:
> 
>> func withNoEscape(@noescape(once) a: () -> (), @noescape(once) b: () -> ()) { /* snip */ }
>> 
>> func foo() {
>> 	let a: Int
>> 	let b: Int
>> 	withNoEscape({ a = 4 }, { b = a + 2})
>> }
> 
> 
> How does the compiler know that `a` has been assigned a value by the time that `b = a + 2` is executed? Nothing says that `withNoEscape` executes the two closures in "visual order”.

It wouldn’t know that, this would be a compile-time error.  Each closure would only be able to use values defined before the call.

-Chris


More information about the swift-evolution mailing list