[swift-evolution] Guaranteed closure execution

Brent Royal-Gordon brent at architechies.com
Mon Feb 1 06:38:11 CST 2016

> The combination of noescape+once is something the compiler can enforce, and because of that, it can provide improved initialization flexibility (and help make things like autoreleasepool feel more statement like).
> The combination of escaping+once is not something the compiler can enforce, and becomes of that, it is little more than documentation.  I’m a huge fan of documentation, but building it into the language like this would mislead people into thinking it IS enforced by the compiler.  Also, this is not how we would build a documentation feature.

The main practical use I imagine this for is completion parameters. These should always be called exactly once, but it's all too easy to write one of these:

	if cantActuallyDoThis() {
		// forgot to return
	guard doThing() else {
		// forgot to call completion

If a parameter is marked `@once`, but there are paths where it is executed twice or zero times, Swift ought to be able to detect that and emit an error. It can also assume that, if the parameter is called once within another closure, and *that* closure is passed to an `@once` parameter, it will be called once. A smart overlay on libdispatch could mark its APIs in appropriate places, and in general, the Clang importer could mark any parameter marked "completion" or "completionHandler" as `@once`. That would mark a large and useful subset of the frameworks.

If the parameter is called within a closure that's passed non-once, it's undecidable; it might be called zero, one, or many times. You could just complain about it, or you could do the analysis both ways, and if neither of them yields `@once`-compliant behavior, give a yell. 

Brent Royal-Gordon

More information about the swift-evolution mailing list