[swift-evolution] extend trailing closure rule

Brent Royal-Gordon brent at architechies.com
Thu Jun 9 03:06:01 CDT 2016


> Here's a common thing to say:
> 
>    UIView.animate(withDuration:0.4, animations: {
>        self.v.backgroundColor = UIColor.red()
>    })
> 
> That's ugly. I'd rather write:
> 
>    UIView.animate(withDuration:0.4) {
>        self.v.backgroundColor = UIColor.red()
>    }
> 
> What stops me is that `animations:` is not eligible for trailing closure syntax, because it isn't the last parameter — `completion:` is. But `completion:` has a default value, namely `nil` — that's why I'm allowed to omit it. So why can't the compiler work its way backwards through the parameters, and say to itself: "Well, I see a trailing closure, and I don't see any `animations:` label or any `completion:` label, so this trailing closure must be the `animations:` argument and the `completions:` argument must be `nil`."

If we may take leave of practical considerations for a moment, I'd like to note that the ideal syntax for a call like this would probably look like:

	UIView.animate(withDuration: 0.4) {
		// animations
	}
	completion { finished in
		// completion
	}

And of course, since `completion` has a default value, this would naturally degrade to:

	UIView.animate(withDuration: 0.4) {
		// animations
	}

I'm guessing this isn't possible because the `completion` could instead be a call to a separate function with a trailing closure. But is there some way we could get something similar? That could significantly improve our handling of multi-block APIs and give trailing closures the ability to emulate more kinds of syntax.

-- 
Brent Royal-Gordon
Architechies



More information about the swift-evolution mailing list