[swift-evolution] Guaranteed closure execution

Félix Cloutier felixcca at yahoo.ca
Mon Feb 1 11:29:12 CST 2016

@Matthew: The @autoclosure was actually an accident; I meant @noescape. :) That said, yes, I think that we'll often want @noescape(once) on @autoclosure parameters.

As for "once?" seems to me that calling a non-escaping closure a second time on accident isn't a very frequent mistake, and when it happens it ought to be very easy to debug. It also doesn't add benefits outside of this verification, so it's unclear to me that the it pulls its own weight. Even as I was writing the @noescape(once) proposal, I was having doubts that it itself would pull its own weight.

@Brent: no matter how useful it is, we can't reasonably prove that an escaping closure is called exactly once without move semantics (and move-only closures). For now, if @once is distinct, it needs to be accompanied by @noescape.

@Gwendal: that's one solution. A third solution would be to enforce that @noescape(once) parameters are executed in parameter order.

Do you have any example of UIKit where a function accepts two closures that could reasonably be marked @noescape(once)?


> Le 1 févr. 2016 à 09:31:53, Matthew Johnson <matthew at anandabits.com> a écrit :
>>> func foo() {
>>> 	let bar: Int
>>> 	withNoEscape { bar = 1 }
>>> }
>>> func withNoEscape(@autoclosure(once) closure: () -> ()) { /* snip */ }
>> Looking back, I do think that there should be a way to exit from `withNoEscape` without calling the closure, so yes, throwing should imply that the closure wasn't executed. If it's possible that `foo` swallowed an error from a throwing `withNoEscape`, the compiler should assume that the variables within haven't been initialized:
> I’m glad to see an @autoclosure func in this thread.  We will want to be able to use this feature with @autoclosure in addition to @noescape.
> As far as exiting without calling the closure, I suggest `@noescape(once?)`.  The `?` indicates the closure may or may not be called, but will not be called more than once.
> This would be handy in the case of the short-circuiting boolean operators, for example:
> @warn_unused_result func &&<T : BooleanType, U : BooleanType>(_ lhs: T, @autoclosure(once?) _ rhs: () throws -> U) rethrows -> Bool
> -Matthew

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160201/650674fc/attachment.html>

More information about the swift-evolution mailing list