[swift-evolution] [Review] SE-0073: Marking closures as executing exactly once

Dmitri Gribenko gribozavr at gmail.com
Wed May 4 12:44:49 CDT 2016


On Wed, May 4, 2016 at 2:24 AM, Gwendal Roué <swift-evolution at swift.org> wrote:
>
>> Le 4 mai 2016 à 08:28, Pyry Jahkola via swift-evolution <swift-evolution at swift.org> a écrit :
>>
>> Here's my review of "SE-0073: Marking closures as executing exactly once".
>>
>>> What is your evaluation of the proposal?
>>
>> +1. I think this is a good idea and should be accepted (without extending the proposed scope).
>>
>> However, I think the proposal should be more explicit about the case when (and whether) the block itself throws. Specifically, I think we should highlight that the criterion that
>>
>>> it must not be executed on any path that throws
>>
>> implies that a @noescape(once) parameter itself cannot throw (until another language change allows otherwise).
>>
>> […]
>>
>> Being able to throw out of a @noescape(once) block […] would complicate the language by requiring that no one catches the error in the scope where uninitialised variables are defined. I suggest adding this remark to the Future directions.
>
> Hello Pyry,
>
> I quite expect being able to throw out of a @noescape(once) block. Maybe the sentence "it must not be executed on any path that throws" should be removed from the proposal, should it have the implications you describe.
>
> Here is below what I expect this proposal to allow. So you see one problematic case?

Hi Gwendal,

What about the following case?

// Function which rethrows closure errors:
func f1(closure: @noescape(once) () throws -> ()) rethrows {
  try closure()
}

let x: AnyObject
f1 {
  if someCondition() { x = MyClass() }
  if someOtherCondition() { throw MyError.Error() }
  x = MyOtherClass()
}

How do you handle memory management for 'x' on the path that throws?
If the rule is that upon returning from f1 via a throw the variable
'x' should not be initialized, then the closure passed to f1 has to
guarantee the deinitialization.  But f1 accepts an arbitrary closure.

Dmitri

-- 
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr at gmail.com>*/


More information about the swift-evolution mailing list