[swift-evolution] Update the signature of ObjectiveC.autoreleasepool [SR-842]

Chris Lattner clattner at apple.com
Tue Mar 29 11:54:06 CDT 2016

> On Mar 24, 2016, at 8:37 AM, Timothy J. Wood <tjw at omnigroup.com> wrote:
>> On Mar 23, 2016, at 10:36 PM, Chris Lattner <clattner at apple.com> wrote:
>> I understand that Jordan withdrew his objection later (because no overload is required) but it still isn't clear to me that autoreleasepool should return a value.
>> Here’s my thought process: autoreleasepool is *intentionally* looking like a statement, not an expression.  Someday I hope it will be possible to break/continue/return/throw out of a closure, and at that point, it will look exactly like a statement.
>> The problem with adding a return value for this is that (so far) we don’t allow the same thing to ‘do’, ‘if’, ‘switch’ and other statements.  I’d argue that autoreleasepool should follow as close as possible in do’s footsteps: if/when we decide to expressionize these statements, at that point should we expressionize autoreleasepool to match.
> If this is the plan, then I’d agree that adding a return value would not be good since it would make that “inlining” more of a breaking change. But, to some extent that ship has already sailed:
> 	func f() {
> 		autoreleasepool {
> 			if (somethingWithLotsOfAutoreleasedObjects()) {
> 				return;
> 			}
> 			somethingImportant()
> 		}
> 	}
> If `autoreleasepool` is turned into a statement instead of a function, the meaning of existing code will silently change in possibly disastrous and hard to detect ways.

Hi Tim,

I don’t think I was clear with what I was suggesting.  My point isn’t that such a change would be source breaking.  My point is that making autoreleasepool returning a value would make it inconsistent with the rest of swift.  If the analogy to statements doesn’t make sense, then maybe the analogy to sequence.forEach {} does:

Why shouldn’t the forEach algorithm return the result of the last execution of its closure argument (suitably wrapped in an optional so it can represent an empty sequence)?  Clearly we could do this.  Clearly it would be useful in certain narrow cases.  

The reason is that Swift is not a pervasively expression oriented language.  We may consider changing that in the future if we can find a design that makes sense, but until and if we do that, it is best for the language and library features to behave consistently, to reduce cognitive dissonance in developers.

> Is there a plan in place to deal with this?

There are several discussions, but none of them are in scope for Swift 3.  My recommendation is that you align with what we have in Swift 3, and if we do ever generalize the language and the rest of the stdlib, we can generalize autoreleasepool along with it.


> The only idea that occurs to me would be to leave `autoreleasepool` as is for a transitional time, deprecated, and add a statement with a new name. Though, if a newly named statement were to be added, then we’re back to being able to leave `autoreleasepool` as a function with a return value and error =)
> With the `rethrow`/`throws` annotation, the migration would be easier since the compiler would catch `try autorelease {...}` as invalid and the extra `try` could be removed.
> Either way, I’m most interested in the `rethrow`/`throws` annotations since passing a value and error back out are most error-prone part, and since it isn’t possible to add in a wrapper. The return value would be possible to re-add in a wrapper, of course.
> -tim

More information about the swift-evolution mailing list