# Ergonomics of \`rethrows\` and \`try\`

**URL:** <https://forums.swift.org/t/ergonomics-of-rethrows-and-try/50392>\
**Category:** Discussion\
**Created:** [July 12, 2021, 9:13pm UTC](https://forums.swift.org/t/ergonomics-of-rethrows-and-try/50392 "2021-07-12T21:13:35Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [July 12, 2021, 9:13pm UTC](https://forums.swift.org/t/ergonomics-of-rethrows-and-try/50392/1 "2021-07-12T21:13:35Z")

</div>

I write a fair number of `rethrows` functions. These are often generic over a protocol, and the caller passes in a closure such as a predicate or transform. (Sometimes more than one.)

In every case, the implementation of the rethrowing function either calls the closures, or passes them along to another rethrowing function, or perhaps wraps them in a larger closure before doing one of those things.

Regardless, every place where the predicate is used, that line must be marked with `try`. Sometimes two tries are needed on the same line, as in:

```swift
try foo{ try !predicate($0) }

```

These `try` markings are all just noise.

Inside a `rethrows` function, any error thrown by the predicate is expected and intended to be rethrown. Nothing is gained by writing `try` there.

The only exception is if the rethrowing function for some reason actually wants to catch an error from one of its arguments. I consider this to be extremely rare, and even then it is only within a `do-try-catch` block that writing `try` makes sense.

When there is no `catch` block, the fact that we are in a `rethrows` function makes the use of `try` superfluous. It is simply unnecessary boilerplate.

I would like to see the rules around `try` improved in this regard, so that in the body of a rethrowing function, uses of its closure parameters do not require `try` (unless they are inside a `do-catch` block).

• • •

As a side tangent, I also think that from a readability standpoint, closure parameters that can be rethrown should be marked something like `rethrown` instead of `throws`.

Marking the parameter `throws` when the function itself is `rethrows` seems incongruous. The whole point of `rethrows` is that the parameter may or may not be throwing, but the word “throws” communicates to the reader that the parameter is necessarily throwing, which is incorrect.

---

<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 12, 2021, 9:35pm UTC](https://forums.swift.org/t/ergonomics-of-rethrows-and-try/50392/2 "2021-07-12T21:35:15Z")

</div>

> [@Nevin](#):
>
> The whole point of `rethrows` is that the parameter may or may not be throwing, but the word “throws” communicates to the reader that the parameter is necessarily throwing, which is incorrect.

Without commenting on the first portion of your post (I haven't personally dealt with writing `rethrows` APIs enough to have an informed opinion), I think I disagree with this characterization of `throws`. It's not `rethrows` that means "the parameter may or may not `throw`," it's the `throws` keyword itself. Since non-`throws` function types are subtypes of their `throws` counterparts, _every_ use of `throws` really means "may or may not throw." Using `rethrows` just indicates "`throw`s when the parameter `throw`s, doesn't `throw` when the parameter doesn't."

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [July 12, 2021, 9:44pm UTC](https://forums.swift.org/t/ergonomics-of-rethrows-and-try/50392/3 "2021-07-12T21:44:33Z")

</div>

Sure that’s fair.

The underlying idea behind the tangent (which I don’t really want to divert this thread for) is that a `rethrows` functions could have some parameters whose errors it rethrows, and other parameters whose errors it catches and does not rethrow.

It would be useful to distinguish between the two, so that the compiler can prevent me from inadvertently rethrowing an error from a parameter which is not intended to be rethrown.

---

<div class="post-metadata">

**Author:** ![dwaite](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dwaite/32/1200_2.png) [@dwaite](https://forums.swift.org/u/dwaite)\
**Post date:** [July 12, 2021, 10:37pm UTC](https://forums.swift.org/t/ergonomics-of-rethrows-and-try/50392/4 "2021-07-12T22:37:54Z")

</div>

> [@Nevin](#):
>
> These `try` markings are all just noise.

I would say they have the same value as `try` in other contexts.

The primary point of `try` is to call attention to the additional program flow control option for the purpose of cleanup and maintaining invariants. A function or method which `rethrows` should also be defining the behavior on thrown error, e.g the documentation from the in-place `Array.sort(by:)`:

> If `areInIncreasingOrder` throws an error during the sort, the elements may be in a different order, but none will be lost.
