[swift-evolution] [Rejected] SE-0097: Normalizing naming for "negative" attributes
clattner at apple.com
Wed Jun 1 23:11:32 CDT 2016
On Jun 1, 2016, at 9:02 PM, Chris Lattner <clattner at apple.com> wrote:
> 2) For noescape, the core team feels that the right solution is for closure arguments to *default* to noescape, which means that the attribute we should really need is @escaping.
To provide some more details, this approach has the following advantages:
- Most functional algorithms written in pure Swift will benefit because they are naturally noescape. The core team feels that this will reduce the boilerplate involved with writing these algorithms.
- The compiler has enough logic in it to provide a great QoI experience when a developer doesn’t think about escaping, and tries to escape a closure - it can provide a fixit that suggests adding @escaping.
- Recent changes (to disallow escaping closures to close over an inout parameter) are pushing the language to prefer noescape closures. noescape closures have also always been the preferred default, since they eliminate a class of retain cycle issues.
- "@autoclosure(escaping)" can be simplified and standardized to "@autoclosure @escaping”
The two primary concerns with taking this direction were that it is would adversely impact resilience, and that imported Objective-C APIs would be too annoying to work with, because the compiler would have to be conservative and assume they are escaping:
On resilience, the concern with this approach is that an API may not thinking about whether a closure parameter should be escaping or not, and this behavior makes it possible that someone could write “V1” of an API and not accidentally promise noescape semantics, but then need it in “V2” of the same API.
John McCall pointed out that resilience in the type system is different than resilience in practice: An API changing to capture a closure and use it long after it was originally passed is likely to break the clients regardless of whether the type system captures this as an issue. He argues (and the argument is strong IMO) that it is *better* for resilient APIs to default to @noescape, since that forces the author of V2 to think about whether they are breaking their clients. If they are doing something that is “logically” noescape in their V2, then they can unsafe bitcast away the escaping aspect of the closure. This is better than changing the client’s view of the API in any case.
On imported Objective-C API, the core team did a quick study of the Cocoa APIs and found that most closure/block parameters are escaping in practice. As such, the core team feels that it isn’t overly burdensome to ask that imported Objective-C APIs annotate their semantically noescape block parameters with the clang __attribute__((noescape)) attribute.
I’m happy to write up this proposal, but won’t have cycles to do so for several weeks. If someone else wants to take it up, that would be great :-)
More information about the swift-evolution