[Accepted] SE-0279: Multiple Trailing Closures

I'm concerned that we'll end up with a decent amount of breakage during/after the trial period, especially given that this proposal now encourages APIs to be designed knowing that the first label will be omitted. Especially if work on this thread moves forward: Renaming Trailing-closure Functions in the Standard Library


I'm afraid this could end up being very similar to SE-0159 Fix Private Access Level. And that was pre-Swift 4.


I don’t think the Core Team’s decision is going to change by complaining about not taking community feedback more seriously into consideration. Don’t get me wrong, I’m also in favor of labeling the first-closure. With that said, let’s not forget that the Core Team is not some evil entity, they are developers like everyone here who helped build Swift, so there’s no need to doubt their intentions, they want what’s best for Swift as we all do.

I think this thread has taken way to much of our time and attention than it should have to. So, I believe we should work on solutions to optionally label first-closures as @Lantua put it (cause for better or for worse it’s their decision at the end).


This is a great point. The proposal as-is encourages future source breaking proposals. Let's not kick that can down the road. If we're going to break source, let's do this right.

If going prioritize source compatibility, the alternative of optionally allowing a label for the first trailing closure eliminates the need to change existing API. Instead, we would get an improvement to existing API: first where: { ... }, etc will be nicer to work with as they already exist.

We have two options that both seem far more reasonable than the accepted design. One is ideal and the other is source compatible. Neither would motivate followup proposals, particularly the source breaking followup that the current design may encourage.


Given the 6-month release cycle for minor Swift versions, and given that Swift 5.3 branch is already cut, I assume this proposal won't be implemented until 1 year later in Swift 5.4.

Even if a new proposal for amending this one is immediately reviewed and accepted as soon as Swift 5.4 is released, the amendment will be implemented at earliest in Swift 5.6, which will be 2 years from now.

How long does the "multiple trailing closures" feature have to stay in the current form, before the core team considers that there is enough "living experience"?

What if something like what has affected SE-0057, SE-0110, and SE-0155 happens down the line, when more things are frozen and more restrictions are imposed on new proposals? Will an amendment for optionally adding the first label still be possible? In at least 2 years in the future?

By that time, there will be more people who have learnt Swift, and wouldn't more people take it as it is, and hold onto how it is because of "backward-compatibility"? Wouldn't this harm future Swift learners, because it IS an inconsistent style, and less likely to be changed as time goes on?

Why can't we just make it right, or as right as it can be in the first place, instead of waiting for years before being allowed an amendment that basically says "told you"?


Me, too.

Some others did as well, and received many ":heart:"s.

It shows it's not just an edge concern.

Honestly I have a hard time seeing why an optional argument label would not be the opptimal solution. I can understand in cases like Binding where you would really want it, but I think in a vast majority of cases where trailing closures are already used, it's just cleaner not to introduce another space-separated token at the call-site.


I think the restriction for the first closure of current proposal leads some apis to be designed in certain way. And they could become unreasonable once the Core Team decides we should lift up the restriction.

I can live fine with the current proposal under Swift 5.x. But it would be better if we could make multiple trailing closures even better when Swift 6+ comes.

BTW, naming apis is hard, with the restriction for first label, it makes namimg even harder to me.

This proposal will be part of Swift 5.3, despite the branch already being cut. It's clear they want it for better SwiftUI code at WWDC next month. (For that matter, so will the final @functionBuilder work that was merged recently.) 5.4 is likely the first chance any changes could make it into the language, however.


Many of us feel that if we were able to design from scratch the declaration and call site should be aligned. Existing API would need to explicitly elide the label with _. If that level of source breakage is unacceptable, then the optional argument label may be the best we can do. But it is not ideal.


I thought the decision of accepting this proposal in the current form might have something to do with how close the WWDC is. I felt the thought cynical, and didn't mention it. But now I see I'm not the only one thinking it.

In all honesty, I think this is somewhat dismissive.

I don’t doubt the intentions for a great language. But there is also the other side of this: Swift is not run by the open source community. It is run by Apple, and their proprietary interests do come first above all.

How does this factor into decisions made about something so seemingly unimportant as this? Who knows. But look at the track record. Last year WWDC was used as a major feature announcement for swift features and then requested that the features be reviewed by Evolution afterwards. This took a large number of people aback as an attempt to “legitimise” a proprietary decision as one that had received independent feedback, despite the fact it had already been announced. Now, a month out from WWDC, we see a proposal pushed through for changes that had seemingly strong arguments in need of change, but there may be a strong organisational reason to get this in as is.

Ultimately, this is their right, and that’s fine. We all knew that by contributing we were asked for opinions, not for votes. But it begs the question what the point is of contributing when the arguments are strong in need of change, and things get pushed through anyway? Are Dub Dub slides more important than good process? While this may seem insulting to the team as a suggestion, looking at it from our perspective, that may indeed seem to be what happened here.


So I ignored the second round of discussion (and most of the first) due to the high amount of discussion but I just wanted to say I'm pretty happy with where this ended up for a few reasons:

  1. It solves a problem I've been annoyed with for a long time
  2. It's fully source compatible
  3. It seems like the smallest amount of syntax needed while still feeling "Swifty" with named parameters

As to the first parameter being named, seems unwise since it would differ so much from the current Closure syntax. Also IMO it's ugly/weird with the typical closure syntax
func myAction(length: 5) completion: {

Something that seems to be under-represented is it could be added, but not removed, later on. Once the feature gets out into the wild with real users there will be a much larger sampling of usage and any related frustrations. At that point if the first parameter label would improve things, it can be made optionally available. However if it were made optionally available now it would be a source breaking change to remove it, even if it turns out to not be useful to most users.

1 Like

Note that many here are arguing that it shouldn't be an option, but that if multiple trailing closures are used, every trailing closure must have a label. This rule is not possible to add later in a source-compatible way (but, as with this proposal, the option to elide the label could be added in a follow-up proposal if usage shows that the difference between single and multiple trailing closure syntax causes friction/confusion).


Large corporations and conspiracy theories seem inseparable these days, but at least in this case there are some pretty good counterpoints.

  1. The proposal had fairly large/meaningful changes between the first and second iteration that would have required significant work. If Apple had things depending on the feature/syntax, why would they "allow" such a large change?
  2. The feature went through two highly active and prolonged review periods. If they're in a rush to get this done...they're doing it wrong.
  3. Probably the biggest counterpoint, Function Builders, a core feature needed for SwiftUI, is still not officially in the language after being proposed almost a year ago. This shows that Apple is not waiting on Swift Evolution to build or release features and the core team isn't pushing through proposals just because Apple wants them. If there are issues with a proposal, it's still iterated on and fixed regardless of when Apple ships their software.
  4. Even ignoring the above reasons, WWDC is still a month away and their final software won't ship for (at least) an additional three months. The Time where Apple would be pushing through evolution changes would be in August, not May.

Changes need to make it into the language version released with the first Xcode beta, and that syntax (ideally) will match all the WWDC slides, videos, and samples. In other words, right now is the time that such changes would be important priorities.


In so far, I think there's no point in re-iterating the issues already raised during the review period. It seems they're already taken into consideration. Some may be misrepresented in the original announcement, which would be a valid follow up to make (and is a separated thing from the issue itself).

It's probably better that we think about how to continue with this, like a path to our logical design, the follow up proposal, etc.


Yes-and that doesn't mean it needs to be an accepted proposal here. I believe Function Builders was shipped with Xcode 11 Beta1 before it even made it to pitch phase. It's also pretty normal for a brand new feature's syntax to change between WWDC and release. SwiftUI being one example, not to mention Swift itself.

It's certainly possible/likely Apple wanted this to go through so they would have time to integrate the changes, but there are enough counter examples of them not pushing things through that it can't be taken as a given without additional evidence.

1 Like

Make that A month and a half :smile:


But it really shouldn't. There are mistakes that get still shipped. SwiftUI and Combine had plenty of them those last year and it took almost a whole year to fix them (wrong property names, wrong initializer names, etc.). These are similar API issues, which later on required solutions such as @_alwaysEmitIntoClient to back port the correct API's.