Remix.run Logo
Defletter a day ago

You misunderstand. In the question given, we don't care about the error, only that an error having occurred is detectable. In Rust, this would be represented as: Result<Option<ExampleType>, ()>, whereas using try? would reinterpret the error as a null, so there's no way to tell the difference between an error-as-null and a returned-null.

This has consequences for config parsing, for example, where a particular subsection (sub-object? keyed struct?) may be optional, so it being missing is perfectly legal. But if you use try?, then there's no way to distinguish between it simply being missing and it being present but malformed. It unfortunately seems like the only other options in Swift is to propagate the error, or revert back to verbose try-catch blocks.

Whereas, in Zig, you can do inline catching and care about the error only as much as you want to, for example:

    // This is equivalent to Swift's try
    const i: ?i32 = try someThrowingFunc();

    // This is equivalent to Swift's try?
    const i: ?i32 = someThrowingFunc() catch null;

    // This is a yielding inline catch block that does not care about the error
    const i: ?i32 = someThrowingFunc() catch brk: {
        logger.warn("Something went wrong!");
        break :brk null;
    }
It's not perfect, I don't love the block-label-break thing, but I much prefer this if only because then the variable can be defensively const, which I do not believe is possible with the kind of code snippet you provided. Also, instead of breaking out, it could capture and return the error or return a new error. It's incredibly versatile.
vips7L a day ago | parent [-]

I’m not misunderstanding. You weren’t making a point about _verbosity_ originally. You were talking about distinguishing errors you care about; which is perfectly possible, you don’t use the construct that says “I don’t care what error it is”.

Defletter 12 hours ago | parent [-]

I did ask "Or rather, how do you do this without returning to the un-ergonomic try-catch?" but I don't want to die on this hill. Can I just assume then that this distinction isn't possible in Swift without returning to try-catch blocks?