[swift-evolution] Guaranteed closure execution

Félix Cloutier felixcca at yahoo.ca
Sun Jan 31 23:12:20 CST 2016


> 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".

Félix



More information about the swift-evolution mailing list