# SE-0286: Forward Scan for Trailing Closures

**URL:** <https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529>\
**Category:** Proposal Reviews\
**Created:** [July 17, 2020, 6:44pm UTC](https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529 "2020-07-17T18:44:05Z")\
**Posts on this page:** 13\
**Page:** 3

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [July 24, 2020, 7:59pm UTC](https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529/41 "2020-07-24T19:59:28Z")

</div>

The updates to the proposal seem sufficiently targeted toward (what seems to be) the only major concerns in this thread. I personally would not be bothered by acceptance of the proposal as-amended if the Core Team believes that's what's best given the time constraints involved.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [July 24, 2020, 8:27pm UTC](https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529/42 "2020-07-24T20:27:57Z")

</div>

I agree, this revision looks good to me.

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [July 24, 2020, 8:31pm UTC](https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529/43 "2020-07-24T20:31:15Z")

</div>

> [@Jumhyn](#):
>
> Why do we still need the heuristic? Shouldn't attempting both the forward scan _and_ the backward scan (and preferring the backward scan in ambiguous cases) be sufficient for source compatibility?

This proposal needs to put us at a good "resting place" both for Swift 5.3+ and Swift 6. The heuristic makes the forward scan work for enough existing APIs that I don't feel like we can simply drop it from Swift 6 without a suitable replacement. For example, I call out this SwiftUI example in the proposal:

```swift
func sheet(
  isPresented: Binding<Bool>,
  onDismiss: (() -> Void)? = nil,
  content: @escaping () -> Content
) -> some View

```

The intent here is clear: the unlabeled trailing closure is supposed to be `content`, because the SwiftUI DSL is formulated that way. If we take away the heuristic but don't have some way to indicate SwiftUI's intent, we have a source break without a good path forward for developers. Of course, a proposal along the lines of what's mentioned in "Future directions" of the proposal could absolutely revoke the heuristic from some future Swift version (be it Swift 6 or later), but it needs to do so with full consideration of the source compatibility impact and the need to support API developers. We can't assume that such a proposal will come along and be accepted in time; SE-0286 has to leave the language in a good place for all of the language versions it touches (Swift 5.3+ and Swift 6+).

SwiftUI isn't an outlier here; I saw a number of examples when I did a [source compatibility run](https://github.com/apple/swift/pull/33069) with the forward+backward scan but _without_ the heuristic (I had the same thought as you).

Doug

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [July 24, 2020, 8:35pm UTC](https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529/44 "2020-07-24T20:35:24Z")

</div>

Thanks for elaborating on that Doug. I'm very satisfied with this iteration of the proposal. Excellent work done on meeting such a tight schedule!

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [July 25, 2020, 3:11am UTC](https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529/45 "2020-07-25T03:11:47Z")

</div>

Doug, this is fantastic; thank you for taking my suggestions and experimenting with them. I really appreciate how you've tried out the design with and without the currently proposed heuristic, and that you've targeted the backward scan legacy affordances narrowly to single trailing closures.

I take it this means that the heuristic you propose would remain part of Swift for the foreseeable future; I think this is fine. In fact, I'd say that it's not an _unprincipled_ compatibility measure, but perhaps fits into a bigger desire to align the behavior of arguments with default values with the behavior of overloads that omit the argument entirely; to the extent that the heuristic brings these two closer, it seems defensible on the basis of that principle, if we see fit to articulate such a principle as something desirable.

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [July 26, 2020, 4:52am UTC](https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529/46 "2020-07-26T04:52:53Z")

</div>

> [@xwu](#):
>
> I take it this means that the heuristic you propose would remain part of Swift for the foreseeable future; I think this is fine. In fact, I'd say that it's not an _unprincipled_ compatibility measure, but perhaps fits into a bigger desire to align the behavior of arguments with default values with the behavior of overloads that omit the argument entirely; to the extent that the heuristic brings these two closer, it seems defensible on the basis of that principle, if we see fit to articulate such a principle as something desirable.

I dropped the "unprincipled" adjective from the revision. It's a reasonable heuristic that's fairly easy to describe and that seems to work quite well in practice, so yes, I'm proposing to keep the heuristic for the foreseeable future.

Doug

---

<div class="post-metadata">

**Author:** ![jawbroken](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jawbroken](https://forums.swift.org/u/jawbroken)\
**Post date:** [July 26, 2020, 2:14pm UTC](https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529/47 "2020-07-26T14:14:50Z")

</div>

This change makes tactical sense, because it deals with one of the grating inconsistencies between function calls with and without trailing closures.

Strategically, I worry that patching over these inconsistencies in a piecemeal fashion is going to lead to the language being left in a local suboptimum, where the design is considered “good enough” and further progress stalls because of source compatibility and other considerations. In the first pitch, where you were staging this change in using attributes, I was going to suggest that you instead just fix this all at once using an attribute (enabling forward scan, callee control of labels, etc.) and either live with that forever or find the resolve to flip the default in future. Fortunately/unfortunately you found a clever way to avoid the attributes here, so that's a less compelling alternative.

So I agree that this is an uphill step, but I worry about where the language is going to end up as a result.

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [July 28, 2020, 4:34am UTC](https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529/48 "2020-07-28T04:34:54Z")

</div>

The (revised) proposal makes so much sense that I just want to +1.

Though I'm a little confused as to why we need to define _"structurally resembles"_ function types. Is it different from _"anything that can use closure"_?

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [July 28, 2020, 6:54pm UTC](https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529/49 "2020-07-28T18:54:52Z")

</div>

> [@Lantua](#):
>
> Though I'm a little confused as to why we need to define _"structurally resembles"_ function types. Is it different from _"anything that can use closure"_ ?

A parameter of type `Any` can accept a closure, but does not "structurally resemble" a function type. I wanted the narrower definition.

Doug

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [July 28, 2020, 8:07pm UTC](https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529/50 "2020-07-28T20:07:05Z")

</div>

Mmm, this is interesting, and I’m not sure I’d appreciated that. Currently, `Any` works with trailing closure syntax:

```swift
func f(_ x: Any) -> String { "Hello, \(x)!" }
print(f { "World" })
// “Hello, (Function)!”

```

Unless there’s a compelling reason, I don’t know that we should break that, and I’m not sure it’s touched on in the proposal.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [July 28, 2020, 8:20pm UTC](https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529/51 "2020-07-28T20:20:18Z")

</div>

SE-0286 has been [accepted with the modifications mentioned above](https://forums.swift.org/t/accepted-with-modifications-se-0286-forward-scan-for-trailing-closures/38836). Thank you all for your reviews.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [July 28, 2020, 8:20pm UTC](https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529/52 "2020-07-28T20:20:22Z")

</div>

Closed on July 28, 2020, 8:20pm UTC



---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [July 29, 2020, 12:05am UTC](https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529/53 "2020-07-29T00:05:17Z")

</div>

> [@xwu](#):
>
> Mmm, this is interesting, and I’m not sure I’d appreciated that. Currently, `Any` works with trailing closure syntax:
> 
> ```swift
> func f(_ x: Any) -> String { "Hello, \(x)!" }
> print(f { "World" })
> // “Hello, (Function)!”
> 
> ```
> 
> Unless there’s a compelling reason, I don’t know that we should break that, and I’m not sure it’s touched on in the proposal.

From the proposal:

> The unlabeled trailing closure will be matched to the next parameter that is either unlabeled or has a declared type that structurally resembles a function type

so this is still well-formed.

Doug

[Previous page](https://forums.swift.org/t/se-0286-forward-scan-for-trailing-closures/38529.md?page=2)
