# Shortened guard statement for throwable functions that must succeed

**URL:** <https://forums.swift.org/t/shortened-guard-statement-for-throwable-functions-that-must-succeed/66002>\
**Category:** Pitches\
**Created:** [July 5, 2023, 9:10pm UTC](https://forums.swift.org/t/shortened-guard-statement-for-throwable-functions-that-must-succeed/66002 "2023-07-05T21:10:08Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![chrisbia](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/chrisbia/32/29915_2.png) [@chrisbia](https://forums.swift.org/u/chrisbia)\
**Post date:** [July 5, 2023, 9:10pm UTC](https://forums.swift.org/t/shortened-guard-statement-for-throwable-functions-that-must-succeed/66002/1 "2023-07-05T21:10:08Z")

</div>

Right now you have to do this:

```swift
guard let _=try? startRecording() else { return }
AVAudioPlayer.play(alert: AlertTones.startRecording)

```

What I would prefer to do is this:

```swift
guard try? startRecording()
AVAudioPlayer.play(alert: AlertTones.startRecording)

```

Which would just return if an error was thrown. Furthermore, you could also do this if you wanted to break instead:

```swift
guard try? startRecording() else break
AVAudioPlayer.play(alert: AlertTones.startRecording)

```

---

<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 5, 2023, 10:26pm UTC](https://forums.swift.org/t/shortened-guard-statement-for-throwable-functions-that-must-succeed/66002/2 "2023-07-05T22:26:39Z")

</div>

This is a commonly rejected change:

> [@Shorthand for guard else empty return statement](https://forums.swift.org/t/shorthand-for-guard-else-empty-return-statement/34404/2):
>
> From the [Swift Evolution common proposals document](https://github.com/apple/swift-evolution/blob/master/commonly_proposed.md): [Infer return for omitted guard body](https://forums.swift.org/t/inferred-return-for-guard-statement/12099/11): It has been proposed many times to allow omission of the guard body for the sake of brevity. However, a core principle of Swift is to make control flow explicit and visible. For example, the try keyword exists solely to indicate to the human reader where thrown errors can happen. Implicit returns would violate this principle, favoring terseness over clarity in a way that isn't typical of Swift. F…

---

<div class="post-metadata">

**Author:** ![intswift](https://avatars.discourse-cdn.com/v4/letter/i/7cd45c/32.png) [@intswift](https://forums.swift.org/u/intswift)\
**Post date:** [July 6, 2023, 8:38am UTC](https://forums.swift.org/t/shortened-guard-statement-for-throwable-functions-that-must-succeed/66002/3 "2023-07-06T08:38:11Z")

</div>

I know this topic has been done to death, but this example could be symptomatic of ergonomics with `try...catch` rather than `guard`.

Often I want to try a throwing function and act if it throws but I don't care what the actual error was. Instead of writing:

```swift
do
{
  try something()
}
catch
{
  // Respond in some way, perhaps throw another error or return nil.
}

```

it would be nice if it could just be:

`try something() else { /* do something else */ }`

which looks a lot like what the OP is wanting to do.

I'm rarely a fan of shorthand in programming languages, but this would remove some noise from the listing.

A related scenario is when wanting to try one thing, and _only if_ that fails then try something else, perhaps trying two or three different fallbacks, and then only if all of them have failed then you do a final catch. Perhaps there's an idiomatic way of expressing such a chain succinctly, but the naive way seems to be lots of `do`s and `catch`es.

---

<div class="post-metadata">

**Author:** ![ibex](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ibex/32/30439_2.png) [@ibex](https://forums.swift.org/u/ibex)\
**Post date:** [July 6, 2023, 12:56pm UTC](https://forums.swift.org/t/shortened-guard-statement-for-throwable-functions-that-must-succeed/66002/4 "2023-07-06T12:56:45Z")

</div>

> [@intswift](#):
>
> `try something() else { /* do something else */ }`

`try` and `catch` combination feels more natural.

```swift
try something() catch { /* handle exception */ }

```

---

<div class="post-metadata">

**Author:** ![anon9791410](https://avatars.discourse-cdn.com/v4/letter/a/9fc348/32.png) [@anon9791410](https://forums.swift.org/u/anon9791410)\
**Post date:** [July 6, 2023, 8:37pm UTC](https://forums.swift.org/t/shortened-guard-statement-for-throwable-functions-that-must-succeed/66002/5 "2023-07-06T20:37:46Z")

</div>

More on that from last week: [Guard-Let-Catch (and If-Let-Catch) to avoid long (nested) do-blocks - #22](https://forums.swift.org/t/guard-let-catch-and-if-let-catch-to-avoid-long-nested-do-blocks/65827/22)

It doesn't help with the chains @intswift mentioned though. It would be better, but still a pyramid of doom with one fewer level of indentation:

```swift
do {
  try oneOfSeveralThrowingFunctions()
} catch {
  do {
    try oneOfSeveralThrowingFunctions()
  } catch {
    do {
      try oneOfSeveralThrowingFunctions()
    } catch {

    }
  }
}

```

```swift
try oneOfSeveralThrowingFunctions() catch {
  try oneOfSeveralThrowingFunctions() catch {
    try oneOfSeveralThrowingFunctions() catch {

    }
  }
}

```

Emulating an `else if` chain necessitates `catch` blocks being able to follow each other:

```swift
try oneOfSeveralThrowingFunctions() catch {
  try oneOfSeveralThrowingFunctions()
} catch {
  try oneOfSeveralThrowingFunctions()
} catch {
  
}

```

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [July 6, 2023, 11:41pm UTC](https://forums.swift.org/t/shortened-guard-statement-for-throwable-functions-that-must-succeed/66002/6 "2023-07-06T23:41:26Z")

</div>

> [@anon9791410](#):
>
> ```swift
> do {
> try oneOfSeveralThrowingFunctions()
> } catch {
> do {
> try oneOfSeveralThrowingFunctions()
> } catch {
> do {
> try oneOfSeveralThrowingFunctions()
> } catch {
> 
> }
> }
> }
> 
> ```

Interestingly we already have a precedent of simplifying a similar pyramid of doom with "if" statements. Following that precedent gets us to this alternative:

```swift
do { // as in "if"
    try oneOfSeveralThrowingFunctions()
} catch do { // as in "else if"
    try oneOfSeveralThrowingFunctions()
} catch do {
    try oneOfSeveralThrowingFunctions()
} catch { // as in "else"
    print(error)
}

```

I still like the simplicity of a simplified `try foo() catch bar()` without a `do`.
