[swift-evolution] Removing "_ in" from empty closures

Erica Sadun erica at ericasadun.com
Sat May 14 15:52:36 CDT 2016

> On May 13, 2016, at 2:16 PM, Joe Groff via swift-evolution <swift-evolution at swift.org> wrote:
>> On May 13, 2016, at 1:06 PM, Matthew Johnson via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> Is anyone planning to write a proposal for this?
> Sounds like you just signed up!
> -Joe

On-list Discussion: Removing "_ in" from empty closures <http://thread.gmane.org/gmane.comp.lang.swift.evolution/17080>
Working gist: https://gist.github.com/erica/3731e24fc252c8e66850e0e02f491281 <https://gist.github.com/erica/3731e24fc252c8e66850e0e02f491281>

Enhancing closure argument flexibility

Proposal: TBD
Authors: Matthew Johnson <https://github.com/anandabits>, Erica Sadun <http://github.com/erica>, Rob Napier <http://github.com/rnapier>
Status: TBD
Review manager: TBD

This proposal loosens closure requirements to support developer flexibility. It removes the _ in requirement that bypasses explicit argument use and allow closures to use any, all, or none of the implicit $n variables as needed or desired.

The Swift-evolution thread about this topic can be found here: Removing "_ in" from empty closures <http://thread.gmane.org/gmane.comp.lang.swift.evolution/17080>

Swift closures that do not explicitly declare an internal parameter list must reference all arguments using implicit $nshorthand names. If they do not, Swift complains that the contextual type for the closure argument "expects n arguments, which cannot be implicitly ignored." This requirement diminishes the efficacy of Swift's $n syntactic sugar. Eliminating the requirement means:

{} becomes a valid 'noop' closure in any context requiring a Void-returning closure. 
Implementations can discard unnecessary code cruft and streamline their minimum implementation from { _(, _)* in } to {}.
{ expression } becomes a valid closure in any context requiring a return value. The expression can offer a simple expression or literal, such as { 42 }.
The closure can mention some of its parameters without having to mention all of its parameters.
 <https://gist.github.com/erica/3731e24fc252c8e66850e0e02f491281#detailed-design>Detailed Design

Under this proposal, parameterized closures types will automatically promote closures that mention a possibly empty subset of implicit arguments. All the following examples will be valid and compile without error or warning:

let _: () -> Void = {}
let _: (Int) -> Void = {} 
let _: (Int, Int) -> Int = { 5 }
let _: (Int, Int) -> Int = { $0 }
let _: (Int, Int) -> Int = { $1 }
In the first two examples, the empty closure literal {} will autopromote to satisfy any void-returning closure type (T...) -> Void. 

// Current
doThing(withCompletion: { _ in })
let x: (T) -> Void = { _ in }

// Proposed
doThing(withCompletion: {})
let x: (T) -> Void = {}
In the remaining examples, the closure will support the return of any expression, whether or not it mentions any or all of the implicit arguments.

 <https://gist.github.com/erica/3731e24fc252c8e66850e0e02f491281#impact-on-existing-code>Impact on Existing Code

This proposal offers no negative effect on existing code, which will continue to compile and run as it did prior to adoption. It offers positive improvements for new code added after adoptions. We believe it would be beneficial for Xcode to scan for {_(, _)* in} patterns during migration and offer fixits to update this code to {}.

 <https://gist.github.com/erica/3731e24fc252c8e66850e0e02f491281#alternatives-considered>Alternatives Considered

We considered and discarded a policy where Swift encourages the use of optional closures in place of simplifying the {}case. This approach does not scale to non-Void cases. It does not align with Cocoa APIs, where most completion handlers are not optional.

 <https://gist.github.com/erica/3731e24fc252c8e66850e0e02f491281#related-proposals>Related Proposals

SE-0029: Remove Implicit Tuple Splat Behavior from Function Applications <https://github.com/apple/swift-evolution/blob/master/proposals/0029-remove-implicit-tuple-splat.md> removed the behavior that allowed $0 to represent either the first argument or a tuple of all arguments.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160514/6685d3e8/attachment.html>

More information about the swift-evolution mailing list