Homogeneous try blocks

I see that we might be getting homogeneous try blocks soon. This is very exciting! Do they have any "exotic" or unexpected applications beyond blocks that return Option<T> or Result<T, E>?

Also, is clippy going to start encouraging writing stuff like try { (x?, y? + 1) } in favor of x.zip(y).map(|(a, b)| (a, b + 1))?

2 Likes

I've had a long tradition of tagging code blocks for things that I've read may have "solutions" in the future. The #1 tag, by far, is autoclone (last time I checked there were over 400 of them in all of our Rust projects). The try-block tag is near the top of the list, so I'm really hyped about this.

Unfortunately I never made a distinction between homogeneous and heterogeneous try blocks, but I suspect the vast majority are homogeneous.

Add to that: Is rustfmt going to be try-block aware immediately? I recall there were some discussions a while back because a language change was made without rustfmt being updated to support it, and people started asking if rustfmt should be able to hold feature stabilization back.

1 Like

I want to be clear, even if this feature is "only" useful for Option and Result that's a big deal. But where else should I think of using it?

The only other stable type that supports ? is ControlFlow in std::ops - Rust, though it's certainly less common.

One place that it plus try blocks can be nice is with Iterator::try_for_each.

For example, its example is currently written

let r = (2..100).try_for_each(|x| {
    if 323 % x == 0 {
        return ControlFlow::Break(x)
    }

    ControlFlow::Continue(())
});
assert_eq!(r, ControlFlow::Break(17));

but with try it can be

let r = (2..100).try_for_each(|x| try {
    if 323 % x == 0 {
        return ControlFlow::Break(x)
    }
});
assert_eq!(r, ControlFlow::Break(17));

instead, which is closer to how you'd write it using an ordinary for loop.

(Not that you'd ever use that specific example, since it's just Iterator::find, but hopefully it helps get the idea across.)

1 Like