SE-0279: Multiple Trailing Closures

There absolutely is a reason, which has been mentioned upthread—sealing existing grammatical holes in the language. Unfortunately I fear that I'm repeating myself, so I'll keep this as brief as possible. A style guide or linting/formatting tool may want to enforce a rule that a method that can be called with a trailing closure is always called with a trailing closure. For example, would you agree that the prevailing convention in Swift is to write this:

let squares = numbers.map { $0 * $0 }

and not this?

let squares = numbers.map({ $0 * $0 })

If so, then it makes sense to enforce that through tooling. But, because of parsing ambiguities, that rule cannot be applied uniformly. If someone writes this:

if array.contains(where: { $0.isABadThing }) {

and tooling looks at that function call, says "hey! that can be a trailing closure!" and applies the transformation, we end up with

if array.contains { $0.isABadThing } {

which no longer compiles. We either have to ignore function calls in conditional statements, or play some other trick like put parentheses around the entire expression:

if (array.contains { $0.isABadThing }) {

...but now that conflicts with a rule that says "the condition in a conditional statement should not be surrounded by parentheses." Language limitations would require these two otherwise unrelated rules to be coupled together, which is a weird special case.

Inserting a label before the closure makes the problem go away, because the brace following the label must unambiguously be a closure:

if array.contains where: { $0.isABadThing } { ...

And now we can uniformly apply the trailing closure rule above.

Requiring braces around the labeled closures brings the ambiguity back again:

if array.contains { where: { $0.isABadThing } } { ...

This is what I mean by looking at the problem holistically. When you said that there was no reason to use a particular syntax, I think that you may have only been considering what a human might write from scratch. But when you work with source-based tooling, having a syntax that removes ambiguities from the language and allows for consistent code without decreasing readability is an excellent reason to prefer it over a syntax that doesn't.

2 Likes