Removing "_ in" from empty closures


(Rob Napier) #1

Currently if a closure takes a value, it requires "_ in" to note that the
value is ignored. This makes sense in many cases, but creates a bit of a
mess in the case of an empty, void-returning closure:

doThing(withCompletion: { _ in })

I'd like to suggest that the compiler promote the empty closure literal {}
to any void-returning closure type so that this could be written:

doThing(withCompletion: {})

This encourages the use of empty closures over optional closures, which I
think is open for debate. In general I try to avoid optionals when they can
be precisely replaced with a non-optional value. Furthermore, most Cocoa
completion handlers are not optional.

The alternative is to not do this, but encourage that any closure that
could reasonably be empty should in fact be optional. I would then want
Cocoa functions with void-returning closures to be imported as optionals to
avoid "{ _ in }".

-Rob


(Joe Groff) #2

+1. In general, I think we should allow implicit arguments, without requiring the closure to use all the implicit $n variables like we do today. These should all be valid:

let _: () -> () = {}
let _: (Int) -> () = {}
let _: (Int, Int) -> Int = { 5 }
let _: (Int, Int) -> Int = { $0 }
let _: (Int, Int) -> Int = { $1 }

-Joe

···

On May 13, 2016, at 9:13 AM, Rob Napier via swift-evolution <swift-evolution@swift.org> wrote:

Currently if a closure takes a value, it requires "_ in" to note that the value is ignored. This makes sense in many cases, but creates a bit of a mess in the case of an empty, void-returning closure:

doThing(withCompletion: { _ in })

I'd like to suggest that the compiler promote the empty closure literal {} to any void-returning closure type so that this could be written:

doThing(withCompletion: {})

This encourages the use of empty closures over optional closures, which I think is open for debate. In general I try to avoid optionals when they can be precisely replaced with a non-optional value. Furthermore, most Cocoa completion handlers are not optional.

The alternative is to not do this, but encourage that any closure that could reasonably be empty should in fact be optional. I would then want Cocoa functions with void-returning closures to be imported as optionals to avoid "{ _ in }".


(David Sweeris) #3

+1, provided it doesn't make life difficult for the compiler.

···

Sent from my iPhone

On May 13, 2016, at 11:13, Rob Napier via swift-evolution <swift-evolution@swift.org> wrote:

Currently if a closure takes a value, it requires "_ in" to note that the value is ignored. This makes sense in many cases, but creates a bit of a mess in the case of an empty, void-returning closure:

doThing(withCompletion: { _ in })

I'd like to suggest that the compiler promote the empty closure literal {} to any void-returning closure type so that this could be written:

doThing(withCompletion: {})

This encourages the use of empty closures over optional closures, which I think is open for debate. In general I try to avoid optionals when they can be precisely replaced with a non-optional value. Furthermore, most Cocoa completion handlers are not optional.

The alternative is to not do this, but encourage that any closure that could reasonably be empty should in fact be optional. I would then want Cocoa functions with void-returning closures to be imported as optionals to avoid "{ _ in }".

-Rob
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Matthew Johnson) #4

Currently if a closure takes a value, it requires "_ in" to note that the value is ignored. This makes sense in many cases, but creates a bit of a mess in the case of an empty, void-returning closure:

doThing(withCompletion: { _ in })

I'd like to suggest that the compiler promote the empty closure literal {} to any void-returning closure type so that this could be written:

doThing(withCompletion: {})

This encourages the use of empty closures over optional closures, which I think is open for debate. In general I try to avoid optionals when they can be precisely replaced with a non-optional value. Furthermore, most Cocoa completion handlers are not optional.

The alternative is to not do this, but encourage that any closure that could reasonably be empty should in fact be optional. I would then want Cocoa functions with void-returning closures to be imported as optionals to avoid "{ _ in }".

+1. In general, I think we should allow implicit arguments, without requiring the closure to use all the implicit $n variables like we do today. These should all be valid:

let _: () -> () = {}
let _: (Int) -> () = {}
let _: (Int, Int) -> Int = { 5 }
let _: (Int, Int) -> Int = { $0 }
let _: (Int, Int) -> Int = { $1 }

+1. Having to explicitly discard unnecessary arguments bugs me every time I have to do it.

···

Sent from my iPad

On May 13, 2016, at 11:16 AM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

On May 13, 2016, at 9:13 AM, Rob Napier via swift-evolution <swift-evolution@swift.org> wrote:

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Cole Campbell) #5

+1. In general, I think we should allow implicit arguments, without requiring the closure to use all the implicit $n variables like we do today. These should all be valid:

let _: () -> () = {}
let _: (Int) -> () = {}
let _: (Int, Int) -> Int = { 5 }
let _: (Int, Int) -> Int = { $0 }
let _: (Int, Int) -> Int = { $1 }

+1. This would be excellent.


(Leonardo Pessoa) #6

+1 here and I don't think it will make life more difficult for the compiler
as it already handles the examples Joe Groff provided. On the contrary, by
removing the need for those "_ in" declarations and checks you make the
life of the compiler easier.

- Leonardo

···

On 13 May 2016 at 13:25, Matthew Johnson via swift-evolution < swift-evolution@swift.org> wrote:

Sent from my iPad

> On May 13, 2016, at 11:16 AM, Joe Groff via swift-evolution < > swift-evolution@swift.org> wrote:
>
>
>> On May 13, 2016, at 9:13 AM, Rob Napier via swift-evolution < > swift-evolution@swift.org> wrote:
>>
>> Currently if a closure takes a value, it requires "_ in" to note that
the value is ignored. This makes sense in many cases, but creates a bit of
a mess in the case of an empty, void-returning closure:
>>
>> doThing(withCompletion: { _ in })
>>
>> I'd like to suggest that the compiler promote the empty closure literal
{} to any void-returning closure type so that this could be written:
>>
>> doThing(withCompletion: {})
>>
>> This encourages the use of empty closures over optional closures, which
I think is open for debate. In general I try to avoid optionals when they
can be precisely replaced with a non-optional value. Furthermore, most
Cocoa completion handlers are not optional.
>>
>> The alternative is to not do this, but encourage that any closure that
could reasonably be empty should in fact be optional. I would then want
Cocoa functions with void-returning closures to be imported as optionals to
avoid "{ _ in }".
>
> +1. In general, I think we should allow implicit arguments, without
requiring the closure to use all the implicit $n variables like we do
today. These should all be valid:
>
> let _: () -> () = {}
> let _: (Int) -> () = {}
> let _: (Int, Int) -> Int = { 5 }
> let _: (Int, Int) -> Int = { $0 }
> let _: (Int, Int) -> Int = { $1 }

+1. Having to explicitly discard unnecessary arguments bugs me every time
I have to do it.

>
> -Joe
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Tony Allevato) #7

+1. I've built APIs before where I wanted a method to take a closure that
had multiple arguments, but where I would also like the client to be able
to ignore the extra arguments if they didn't need that level of detail, and
it would be nice to not require them to acknowledge those extra parameters
with `_`. Right now, I have to provide multiple overloads for that:

func foo(body: (Arg1, Arg2, Arg3) -> Result) { ... }
func foo(body: (Arg1, Arg2) -> Result) { ... }
func foo(body: (Arg1) -> Result) { ... }

Allowing closure to just work with fewer arguments would make this bloat go
away.

···

On Fri, May 13, 2016 at 9:25 AM Matthew Johnson via swift-evolution < swift-evolution@swift.org> wrote:

Sent from my iPad

> On May 13, 2016, at 11:16 AM, Joe Groff via swift-evolution < > swift-evolution@swift.org> wrote:
>
>
>> On May 13, 2016, at 9:13 AM, Rob Napier via swift-evolution < > swift-evolution@swift.org> wrote:
>>
>> Currently if a closure takes a value, it requires "_ in" to note that
the value is ignored. This makes sense in many cases, but creates a bit of
a mess in the case of an empty, void-returning closure:
>>
>> doThing(withCompletion: { _ in })
>>
>> I'd like to suggest that the compiler promote the empty closure literal
{} to any void-returning closure type so that this could be written:
>>
>> doThing(withCompletion: {})
>>
>> This encourages the use of empty closures over optional closures, which
I think is open for debate. In general I try to avoid optionals when they
can be precisely replaced with a non-optional value. Furthermore, most
Cocoa completion handlers are not optional.
>>
>> The alternative is to not do this, but encourage that any closure that
could reasonably be empty should in fact be optional. I would then want
Cocoa functions with void-returning closures to be imported as optionals to
avoid "{ _ in }".
>
> +1. In general, I think we should allow implicit arguments, without
requiring the closure to use all the implicit $n variables like we do
today. These should all be valid:
>
> let _: () -> () = {}
> let _: (Int) -> () = {}
> let _: (Int, Int) -> Int = { 5 }
> let _: (Int, Int) -> Int = { $0 }
> let _: (Int, Int) -> Int = { $1 }

+1. Having to explicitly discard unnecessary arguments bugs me every time
I have to do it.

>
> -Joe
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Chris Lattner) #8

I agree, but I consider this to be an obvious bug in the compiler. I don’t think it requires a proposal.

Unfortunately it is non-trivial to fix…

-Chris

···

On May 13, 2016, at 9:16 AM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

This encourages the use of empty closures over optional closures, which I think is open for debate. In general I try to avoid optionals when they can be precisely replaced with a non-optional value. Furthermore, most Cocoa completion handlers are not optional.

The alternative is to not do this, but encourage that any closure that could reasonably be empty should in fact be optional. I would then want Cocoa functions with void-returning closures to be imported as optionals to avoid "{ _ in }".

+1. In general, I think we should allow implicit arguments, without requiring the closure to use all the implicit $n variables like we do today. These should all be valid:

let _: () -> () = {}
let _: (Int) -> () = {}
let _: (Int, Int) -> Int = { 5 }
let _: (Int, Int) -> Int = { $0 }
let _: (Int, Int) -> Int = { $1 }


(Dave Abrahams) #9

+1

···

on Fri May 13 2016, Joe Groff <swift-evolution@swift.org> wrote:

On May 13, 2016, at 9:13 AM, Rob Napier via swift-evolution <swift-evolution@swift.org> wrote:

Currently if a closure takes a value, it requires "_ in" to note
that the value is ignored. This makes sense in many cases, but
creates a bit of a mess in the case of an empty, void-returning

closure:

doThing(withCompletion: { _ in })

I'd like to suggest that the compiler promote the empty closure
literal {} to any void-returning closure type so that this could be
written:

doThing(withCompletion: {})

This encourages the use of empty closures over optional closures,
which I think is open for debate. In general I try to avoid
optionals when they can be precisely replaced with a non-optional
value. Furthermore, most Cocoa completion handlers are not optional.

The alternative is to not do this, but encourage that any closure
that could reasonably be empty should in fact be optional. I would
then want Cocoa functions with void-returning closures to be
imported as optionals to avoid "{ _ in }".

+1. In general, I think we should allow implicit arguments, without
requiring the closure to use all the implicit $n variables like we do
today. These should all be valid:

let _: () -> () = {}
let _: (Int) -> () = {}
let _: (Int, Int) -> Int = { 5 }
let _: (Int, Int) -> Int = { $0 }
let _: (Int, Int) -> Int = { $1 }

--
-Dave


(Erica Sadun) #10

+1. Good riddance to bad code baggage.

-- E

···

On May 13, 2016, at 11:14 AM, Cole Campbell via swift-evolution <swift-evolution@swift.org> wrote:

+1. In general, I think we should allow implicit arguments, without requiring the closure to use all the implicit $n variables like we do today. These should all be valid:

let _: () -> () = {}
let _: (Int) -> () = {}
let _: (Int, Int) -> Int = { 5 }
let _: (Int, Int) -> Int = { $0 }
let _: (Int, Int) -> Int = { $1 }

+1. This would be excellent.


(Jacob Bandes-Storch) #11

+1, seems logical to me:

    let x: [T] = []
    let x: [T:U] = [:]
    let x: T->() = {}

Jacob

···

On Fri, May 13, 2016 at 10:48 AM, Erica Sadun via swift-evolution < swift-evolution@swift.org> wrote:

On May 13, 2016, at 11:14 AM, Cole Campbell via swift-evolution < > swift-evolution@swift.org> wrote:
>
>
>> +1. In general, I think we should allow implicit arguments, without
requiring the closure to use all the implicit $n variables like we do
today. These should all be valid:
>>
>> let _: () -> () = {}
>> let _: (Int) -> () = {}
>> let _: (Int, Int) -> Int = { 5 }
>> let _: (Int, Int) -> Int = { $0 }
>> let _: (Int, Int) -> Int = { $1 }
>
> +1. This would be excellent.

+1. Good riddance to bad code baggage.

-- E

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Erica Sadun) #12

https://bugs.swift.org/browse/SR-1528

-- E

···

On May 14, 2016, at 11:16 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On May 13, 2016, at 9:16 AM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

This encourages the use of empty closures over optional closures, which I think is open for debate. In general I try to avoid optionals when they can be precisely replaced with a non-optional value. Furthermore, most Cocoa completion handlers are not optional.

The alternative is to not do this, but encourage that any closure that could reasonably be empty should in fact be optional. I would then want Cocoa functions with void-returning closures to be imported as optionals to avoid "{ _ in }".

+1. In general, I think we should allow implicit arguments, without requiring the closure to use all the implicit $n variables like we do today. These should all be valid:

let _: () -> () = {}
let _: (Int) -> () = {}
let _: (Int, Int) -> Int = { 5 }
let _: (Int, Int) -> Int = { $0 }
let _: (Int, Int) -> Int = { $1 }

I agree, but I consider this to be an obvious bug in the compiler. I don’t think it requires a proposal.

Unfortunately it is non-trivial to fix…


(Nicholas Maccharoli) #13

+1

All the best,

Nicholas

Linked in:
http://lnkd.in/328U22

···

On Mon, May 16, 2016 at 7:27 AM, Dave Abrahams via swift-evolution < swift-evolution@swift.org> wrote:

on Fri May 13 2016, Joe Groff <swift-evolution@swift.org> wrote:

>> On May 13, 2016, at 9:13 AM, Rob Napier via swift-evolution < > swift-evolution@swift.org> wrote:
>>
>> Currently if a closure takes a value, it requires "_ in" to note
>> that the value is ignored. This makes sense in many cases, but
>> creates a bit of a mess in the case of an empty, void-returning
>
>> closure:
>>
>> doThing(withCompletion: { _ in })
>>
>> I'd like to suggest that the compiler promote the empty closure
>> literal {} to any void-returning closure type so that this could be
>> written:
>>
>> doThing(withCompletion: {})
>>
>> This encourages the use of empty closures over optional closures,
>> which I think is open for debate. In general I try to avoid
>> optionals when they can be precisely replaced with a non-optional
>> value. Furthermore, most Cocoa completion handlers are not optional.
>>
>> The alternative is to not do this, but encourage that any closure
>> that could reasonably be empty should in fact be optional. I would
>> then want Cocoa functions with void-returning closures to be
>> imported as optionals to avoid "{ _ in }".
>
> +1. In general, I think we should allow implicit arguments, without
> requiring the closure to use all the implicit $n variables like we do
> today. These should all be valid:
>
> let _: () -> () = {}
> let _: (Int) -> () = {}
> let _: (Int, Int) -> Int = { 5 }
> let _: (Int, Int) -> Int = { $0 }
> let _: (Int, Int) -> Int = { $1 }

+1

--
-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(John McCall) #14

Yeah, this is just a bug which several people have made various efforts over the last three years to fix. It's not easy.

John.

···

On May 14, 2016, at 10:16 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:
On May 13, 2016, at 9:16 AM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

This encourages the use of empty closures over optional closures, which I think is open for debate. In general I try to avoid optionals when they can be precisely replaced with a non-optional value. Furthermore, most Cocoa completion handlers are not optional.

The alternative is to not do this, but encourage that any closure that could reasonably be empty should in fact be optional. I would then want Cocoa functions with void-returning closures to be imported as optionals to avoid "{ _ in }".

+1. In general, I think we should allow implicit arguments, without requiring the closure to use all the implicit $n variables like we do today. These should all be valid:

let _: () -> () = {}
let _: (Int) -> () = {}
let _: (Int, Int) -> Int = { 5 }
let _: (Int, Int) -> Int = { $0 }
let _: (Int, Int) -> Int = { $1 }

I agree, but I consider this to be an obvious bug in the compiler. I don’t think it requires a proposal.

Unfortunately it is non-trivial to fix…


(Jordan Rose) #15

Sorry to find this thread late. I don’t think this is just a bug; it’s also a way to check that a parameter isn’t getting forgotten. For a single-expression closure that’s probably overkill, but maybe we’d keep the restriction for multi-statement closures?

Jordan

···

On May 14, 2016, at 22:16, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On May 13, 2016, at 9:16 AM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

This encourages the use of empty closures over optional closures, which I think is open for debate. In general I try to avoid optionals when they can be precisely replaced with a non-optional value. Furthermore, most Cocoa completion handlers are not optional.

The alternative is to not do this, but encourage that any closure that could reasonably be empty should in fact be optional. I would then want Cocoa functions with void-returning closures to be imported as optionals to avoid "{ _ in }".

+1. In general, I think we should allow implicit arguments, without requiring the closure to use all the implicit $n variables like we do today. These should all be valid:

let _: () -> () = {}
let _: (Int) -> () = {}
let _: (Int, Int) -> Int = { 5 }
let _: (Int, Int) -> Int = { $0 }
let _: (Int, Int) -> Int = { $1 }

I agree, but I consider this to be an obvious bug in the compiler. I don’t think it requires a proposal.


(Matthew Johnson) #16

Is anyone planning to write a proposal for this?

···

Sent from my iPhone

On May 13, 2016, at 3:02 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org> wrote:

+1, seems logical to me:

    let x: [T] = []
    let x: [T:U] = [:]
    let x: T->() = {}

Jacob

On Fri, May 13, 2016 at 10:48 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:
On May 13, 2016, at 11:14 AM, Cole Campbell via swift-evolution <swift-evolution@swift.org> wrote:
>
>
>> +1. In general, I think we should allow implicit arguments, without requiring the closure to use all the implicit $n variables like we do today. These should all be valid:
>>
>> let _: () -> () = {}
>> let _: (Int) -> () = {}
>> let _: (Int, Int) -> Int = { 5 }
>> let _: (Int, Int) -> Int = { $0 }
>> let _: (Int, Int) -> Int = { $1 }
>
> +1. This would be excellent.

+1. Good riddance to bad code baggage.

-- E

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(John McCall) #17

The bug we're talking about is that closures have to have a reference to $n when there are n+1 parameters.

John.

···

On May 19, 2016, at 4:13 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

On May 14, 2016, at 22:16, Chris Lattner via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On May 13, 2016, at 9:16 AM, Joe Groff via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

This encourages the use of empty closures over optional closures, which I think is open for debate. In general I try to avoid optionals when they can be precisely replaced with a non-optional value. Furthermore, most Cocoa completion handlers are not optional.

The alternative is to not do this, but encourage that any closure that could reasonably be empty should in fact be optional. I would then want Cocoa functions with void-returning closures to be imported as optionals to avoid "{ _ in }".

+1. In general, I think we should allow implicit arguments, without requiring the closure to use all the implicit $n variables like we do today. These should all be valid:

let _: () -> () = {}
let _: (Int) -> () = {}
let _: (Int, Int) -> Int = { 5 }
let _: (Int, Int) -> Int = { $0 }
let _: (Int, Int) -> Int = { $1 }

I agree, but I consider this to be an obvious bug in the compiler. I don’t think it requires a proposal.

Sorry to find this thread late. I don’t think this is just a bug; it’s also a way to check that a parameter isn’t getting forgotten. For a single-expression closure that’s probably overkill, but maybe we’d keep the restriction for multi-statement closures?


(Joe Groff) #18

Is anyone planning to write a proposal for this?

Sounds like you just signed up!

-Joe

···

On May 13, 2016, at 1:06 PM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

Sent from my iPhone

On May 13, 2016, at 3:02 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org> wrote:

+1, seems logical to me:

    let x: [T] = []
    let x: [T:U] = [:]
    let x: T->() = {}

Jacob

On Fri, May 13, 2016 at 10:48 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:
On May 13, 2016, at 11:14 AM, Cole Campbell via swift-evolution <swift-evolution@swift.org> wrote:
>
>
>> +1. In general, I think we should allow implicit arguments, without requiring the closure to use all the implicit $n variables like we do today. These should all be valid:
>>
>> let _: () -> () = {}
>> let _: (Int) -> () = {}
>> let _: (Int, Int) -> Int = { 5 }
>> let _: (Int, Int) -> Int = { $0 }
>> let _: (Int, Int) -> Int = { $1 }
>
> +1. This would be excellent.

+1. Good riddance to bad code baggage.

-- E

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Matthew Johnson) #19

Is anyone planning to write a proposal for this?

Sounds like you just signed up!

Lol, sounds good. Just don't want to duplicate efforts! :slight_smile:

···

Sent from my iPhone

On May 13, 2016, at 3:16 PM, Joe Groff <jgroff@apple.com> wrote:

On May 13, 2016, at 1:06 PM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

-Joe

Sent from my iPhone

On May 13, 2016, at 3:02 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org> wrote:

+1, seems logical to me:

   let x: [T] = []
   let x: [T:U] = [:]
   let x: T->() = {}

Jacob

On Fri, May 13, 2016 at 10:48 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

On May 13, 2016, at 11:14 AM, Cole Campbell via swift-evolution <swift-evolution@swift.org> wrote:

+1. In general, I think we should allow implicit arguments, without requiring the closure to use all the implicit $n variables like we do today. These should all be valid:

let _: () -> () = {}
let _: (Int) -> () = {}
let _: (Int, Int) -> Int = { 5 }
let _: (Int, Int) -> Int = { $0 }
let _: (Int, Int) -> Int = { $1 }

+1. This would be excellent.

+1. Good riddance to bad code baggage.

-- E

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Erica Sadun) #20

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

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
<https://gist.github.com/erica/3731e24fc252c8e66850e0e02f491281#introduction>Introduction

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>
<https://gist.github.com/erica/3731e24fc252c8e66850e0e02f491281#motivation>Motivation

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.

···

On May 13, 2016, at 2:16 PM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

On May 13, 2016, at 1:06 PM, Matthew Johnson via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Is anyone planning to write a proposal for this?

Sounds like you just signed up!

-Joe