[Pitch #1] Forward scan matching for trailing closures (source breaking)

Essentially, yes.

Even if the API designer doesn't provide a label, _: would be allowed, since we are simply allowing on the first trailing closure what's already required for the remaining trailing closures.

I would surmise that tooling would offer one completion, whichever is considered the best practice. As I said before, I expect that we would coalesce around a set of best practices fairly quickly once the feature is used in the wild.

I think that's a good end goal. The core team has demonstrated that they consider this process of refining trailing closures to be one that can have intermediate "resting" points, so returning control to the callee with an attribute is a separable proposal that can be considered on its own merits.

I raise the issue of allowing the initial trailing closure to be labeled and fold it here with forward scan matching not because I want to combine two disparate things and push some other agenda, but because (as I wrote in my analysis above) the lack of such an option is at the crux of the present problem and addressing it is also key to a congenial solution.

It would have to be at the function declaration level; otherwise, it would have to be applied to each possible trailing closure parameter, since any of them can be matched with an unlabeled first trailing closure. But again, this is a separable discussion and best done separately. I don't want to hijack this thread about forward scan matching.

Off the top of my head: in the case where labels repeat (which is much more common now that we've standardized on using prepositions such as by, of, or to for labels). There will be other situations, too, I'm sure.

1 Like

It doesn't really address the problem I call out, though. SE-0279 is about extending the existing trailing closure syntax, to allow more trailing closures to be specified with labels. The feedback in the first review was strongly toward making trailing closures an extension of the existing syntax, not a new thing.

What you're proposing is to layer new semantics on top, which kicks in when the first trailing closure argument is labeled. Yes, it's additive and therefore not source-breaking. However, consider my animate(withDuration:animations:completion:) example: the way people use such an API today, with an unlabeled trailing closure, is still broken. Your proposal is that the caller have another way to spell the call site that isn't broken:

UIView.animate(withDuration: 0.3) animations: {
  self.view.alpha = 0


UIView.animate(withDuration: 0.3) animations: {
  self.view.alpha = 0
} completion: { _ in

So the label on the first trailing closure is effectively optional, but when it's there, it changes the direction in which trailing closures are matched. I don't think that's a good place for us to land, even as an intermediate step.


Yes, you're absolutely right. Given the option, I think SwiftUI would much prefer to have some way to state that onDismiss could never use a trailing closure.

I definitely agree that having an attribute supporting backward scan in the long run would be unfortunate.

I don't like the ability to write labels for trailing closures in the first position, but I agree with the rest of what you've said here.

I've gotten a lot of useful signal out of this discussion already, and have a lighter-weight pitch to bring up (with no attributes). I'm going to go ahead and do that in a separate thread, so that the attribute-focused discussion here doesn't muddy that discussion.