[Pitch] Guard that works with 'try'

Hello everyone, this is my first topic, so i am sorry if i did not post it where it should.

My suggestion would be to extend the guard support to work with try as well.

Current:

func processConfig() {
    do {
        let config = try loadApplicationConfig()
        // Continue with config...
    } catch {
        // error is implicit
        print("Failed to load config: \(error.localizedDescription)")
        return
    }
}

or

func processConfig() {
    let config: ApplicationConfig
    do {
        config = try loadApplicationConfig()
    } catch {
        // error is implicit
        print("Failed to load config: \(error.localizedDescription)")
        return
    }
    // Continue with config...
}

Proposed:

func processConfig() {
    guard let config = try loadApplicationConfig() else {
        // error is implicit, just like it catch
        print("Failed to load config: \(error.localizedDescription)")
        return
    }
    // Continue with config...
}

I think it would work great with the cases were we dont do a lot of throwing calls and it doing a traditional do-catch simply reduces the readability through additional brackets.

1 Like

That's an interesting one, but unfortunately, it conflicts with the type system. guard let is designed to work with optionals, but try expressions return concrete values. In your example, there wouldn't be an ApplicationConfig? to unwrap
Swift keeps optional unwrapping and error handling separate by design. For reducing nesting, you might consider making your function throws or using early returns within your do-catch blocks instead

I would also really appreciate a syntax like this; it is actually one of the very few things in Swift that I wish was more flexible like in Rust, especially once you start bringing typed throws into the picture. Having to place things inside a do/catch block becomes not only tedious but can double complexity, often because we have no way to assign values directly from a do/catch. My guess is using guard in the proposed way wouldn't be feasible from a backwards compatibility standpoint, but I have also felt the pain of the underlying problem.

1 Like

There's a lot of history with this topic (proposed variously as guard try, guard...catch, do try...catch, etc.), which you can find in these forums:

https://forums.swift.org/search?q=guard%20try

1 Like