# Principles for Trailing Closure Evolution Proposals

**URL:** <https://forums.swift.org/t/principles-for-trailing-closure-evolution-proposals/37265>\
**Category:** Discussion\
**Created:** [June 5, 2020, 10:47pm UTC](https://forums.swift.org/t/principles-for-trailing-closure-evolution-proposals/37265 "2020-06-05T22:47:24Z")\
**Posts on this page:** 1\
**Showing post:** 11

<div class="post-metadata">

**Author:** ![mattpolzin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mattpolzin/32/6041_2.png) [@mattpolzin](https://forums.swift.org/u/mattpolzin)\
**Post date:** [June 7, 2020, 4:33pm UTC](https://forums.swift.org/t/principles-for-trailing-closure-evolution-proposals/37265/11 "2020-06-07T16:33:46Z")

</div>

I share some of the concerns touched on by @DevAndArtist just now. I'll elaborate below.

I appreciate that this conversation is happening right now. I learned a lot by reading over the OP in this thread that will make me a better API designer _period_. To frame up the following, I am generally in favor of the syntax settled on for multiple trailing closures. That said, I think it is incumbent upon us (the community _and_ the core team and language maintainers) to move quickly on follow-ups for trailing closures because multiple trailing closures have already been accepted but we don't yet have a good solution to the call-site clarity or API designer control over call-site legibility.

My thesis is that the middle-ground we have now is going to result in very real downsides in the short term and I am not convinced we can clean those downsides up easily because APIs will be designed around what we have today, not what we hope to have in the future, and APIs will be used the best they can be despite future changes potentially resulting in breaking changes to those call-sites. Note that here I am not referring to breaking changes mandated by Swift Evolution, but rather breaking changes to library APIs as library authors gain hypothetical tools like attributes that force labels to be explicit.

I think it is reasonable to say that multiple trailing closures do not actually maintain the status quo even if they ostensibly follow the same rules as single trailing closure already did. Where before an API designer needed to assume that the caller might omit the argument label for the last closure, now the problem has multiplied to the API designer needing to assume that any of the argument labels for the _n_ last closures might be omitted; note, I am not saying that _all_ of the arguments can be omitted, but rather that _any one of them_ might be, depending on where the call-site begins using trailing closures. This was illustrated well [here](https://forums.swift.org/t/se-0279-multiple-trailing-closures-amended/35435/2) under the details of Jordan's "more nebulous note."

It is really unfortunate to be faced with the questions: Do I design my API with the best possible multiple trailing closure experience or do I design my API so that call sites are never confusing? Is it responsible of me to recommend trailing closure syntax (by way of example code) in my documentation given the fact that some call sites will benefit and others will not?

I have already experienced this problem in designing my own APIs in the past weeks and trying to think about how they will interact with multiple trailing closure syntax. It puts us in an awkward position: We can design something that works really well sometimes and not very well at all other times and it is not even strictly speaking always a matter of the end-user's stylistic _preference_. I'll give a bit of a silly example in the expansion below.

> **Example**
>
> I have a function with the following signature:
> 
> ```swift
> public func validate<T>(
> _ description: String,
> check validate: @escaping (ValidationContext<T>) -> Bool,
> when predicate: @escaping (ValidationContext<T>) -> Bool
> )
> 
> ```
> 
> Multiple trailing closures can make the call-site quite pretty (in my opinion):
> 
> ```swift
> validate("Two Ones Make a Two") {
> Two($0.oneValues) != nil
> } when: { 
> $0.oneValues.count == 2
> }
> 
> ```
> 
> However, if complicated validations start to become smart to write as named closures, the call-site loses the benefit of explicitly labeling the last closure as "when" unless the user decides to arbitrarily hold themselves to the rule that "calling `validate()` with one trailing closure is disallowed but calling it with two trailing closures is preferred":
> 
> ```swift
> let allOnesAdd: (ValidationContext<T>) -> Bool = ...
> 
> validate("All Ones Add Up", check: allOnesAdd) { 
> $0.oneValues.count > 0
> }
> 
> ```
> 
> Obviously, this is analogous to the existing decision an end-user must make of whether or not to use single trailing closures based on call-site clarity, but now as an API designer I can no longer just "assume any given user will not use the last closure argument label." Instead I must assume that "some users will use it and some users won't" and "some users will prefer to use it or not depending on the circumstances."

---

_[View the full topic](https://forums.swift.org/t/principles-for-trailing-closure-evolution-proposals/37265)._
