SwiftUI uses non-standard extensions that nobody else can use; it isn’t Swift. That means we basically have to take the word of Apple‘s framework team that this is the best design to solve the problem - which is something I’m frankly not willing to do, and I don’t think it’s enough to make such a massive change to the language.
I’ve seen Apple engineers apply Swift with varying degrees of competence (which is not to slate those engineers or Apple - it takes a lot of time and experience to learn how best to design APIs in a new language, and ideas evolve over time). Different teams also appear to have different ideas about best-practices (e.g. Foundation‘s Data is it’s own slice type, something that the standard library explicitly rejected for types like Array and String).
Maybe there is a much better design for sections which doesn’t involve trailing closures. I don’t know - I can’t use the same features that SwiftUI does, so I can’t explore it. If I could, maybe I’d come back and say that I agree with the SwiftUI team that this is absolutely necessary and worth the complexity, but as things stand I‘m supposed to just take it on faith.
I sympathize with your concerns about proposals passing without community review and feedback. You’re right SwiftUI uses a non-standard feature, but that definitely doesn’t mean it’s not Swift. All this has been thoroughly discussed in another thread and I believe that is not the right one to continue this discussion.
Despite your concerns about Apple “overly controlling” the language (feel free to correct me if I misunderstood), I think that this is arguably a good addition to the language. For those unwilling to use it, I think that Editor Formatting Tools would be a better course of action than the prohibition of multiple trailing closures.
Besides, it’s likely that once Function Builders become an official language feature, much more libraries will use DSLs and would benefit from the proposed feature.
I think Multiple Trailing Closures has its merits in writing different categories of params especially for long block of function/closure arguments.
For example, func F(v,f,v,f,f,...) take mixed var/func params, with MTC we put var args in (v...) and trail func args to the end of (v...) f: {}..., as developers we simply put value params in (...) first, and write long closure argument slowly over time at the end of function one by one.
fun (v...)
c1: { take M mins...}
c2: { take N mins...}
...
_ : {maybe take hours...}
different part of code take different type/category of params var/func.
The problem is how to write it conveniently and clearly, both for dev to read and compiler to parse.
Label everything, the first one can be omitted/optional for traditional single trailing closure compatibility probably is the common answer to this pitch.
EDIT: It was said that the above code doesn’t clearly show that the unlabeled closure is meant to represent the package’s products and I agree. I thought that was obvious and that I didn’t have to explicitly point this out (my bad). Such an implementation would not be really expressive with the currently proposed feature. Because of that I also don’t think it should be added without the ability to use labels in all the closures. Nonetheless, I do feel it is a step in the right direction as it holds great potential.
It is a concern, but not the point I was making, so you did misunderstand.
I’m saying that there are many alternative designs for sections in DSLs which won’t use multiple trailing closures. This community, which routinely demonstrates novel API patterns, has not explored those alternative designs because we can’t use function builder DSLs in our own libraries.
We are instead left to assume that SwiftUI‘s solution is the best there is, and that multiple trailing closures must be necessary. That is not a very compelling argument IMO.
Perhaps, if it is a common need in that particular context, it could be limited to function builders (which are very unlike regular Swift closures anyway). Again, lots of unexplored options because function builders are not currently part of Swift.
I realize it's already past the review deadline, but I just want to add a quick comment on the suggestion about SwiftPM package declaration syntax by @filip-sakel.
There seems to be no indication on what the first closure is about, and it makes the declaration difficult to understand even for developers who have worked with SwiftPM previously, and pretty much impossible to figure out for newcomers.
This is actually a great example of how well-designed APIs might become a lot less comprehensible if this proposal is accepted.
I'm imagining SwiftUI code with a couple extra () and it seems fine. The commas aren't unnecessary, the labels aren't unnecessary. And nobody is bothered to have typed them.
But like I said, we could just type function callers like this myFunction 100, {} {}, true and have no labels and have no (). In fact, we could look for every case in swift code where the parser/compiler could guess what you're trying to do and just do that so we don't have to type anything. Do we even need the func keyword? or var keyword? Many language don't have them. Imaging not having to type func or var at all, It would really clean things up.
UNRELATED OPINION
I think that Function Builders are a hack job there require too much explanation for how they work just to explain why you can't do a proper IF statement of Switch (among a million other basic things that would be solved if we didn't have function builders at all). It's a dissertation that isn't worth the trouble. It also doesn't solve a problem except typing .addSubview() and allowing the chaining modifying functions. Which is NOT clean. I'm disappointed that it wasn't well thought out before being adopted. I prefer to stay off this topic but my bias is necessary to understand my perspective here.
I love this proposal and think it is a net positive for Swift in it's current form. I do have a few small concerns.
As @bjhomer pointed out above, we used to special case the first parameter label for functions and we removed that. It simplified the rules for how parameter labels worked, and made learning the language easier.
Prior to SE-0046, there was a way to opt the function in to having a label on the first parameter, an affordance we don't have with this proposal for labels on the first trailing closure.
If the author of an API wants to elide the first parameter label, they can opt in with an _. We could go the other direction and default to no parameter label, and have a way to opt out (I believe you did this by adding a # or some other character for the first parameter label in a function), but this adds extra syntax and I don' think it's worth it.
We can (in a future proposal perhaps) consider deprecating the behavior in single trailing closures of dropping the label by default to bring all trailing closures in line with each other.
Summary: +1 overall, but lets get rid of the special case for the first trailing closure.
First of all, I find the description of the problem in the proposal to be incoherent. First, it identifies “the” problem with trailing closure syntax as that it only applies to the last closure (i.e. we don't get to omit enough argument labels), and then it goes on to give an analysis where the actual problem is that a label is omitted that was needed for clarity. Making it possible to sugar closures in more argument positions can't help with that.
The real issue is that API designers don't have control over usage of trailing closure. For APIs with more than one closure and which all the labels are required for clarity, the API designer should be able to disallow trailing closures, which would fix the problem much more elegantly.