Can this just be done as a lambda that is immediately evaluated? It's just much more verbose.

    let x = (|| -> Result<i32, std::num::ParseIntError> {
         Ok("1".parse::<i32>()?
          + "2".parse::<i32>()?
          + "3".parse::<i32>()?)
    })();

That prevents other control flow mechanisms (return, break) from operating past the function boundary. In general, I avoid single-callsite functions as much as possible (including the iterator api) for this reason.

It sounds like you're fighting the language - Rust is sort of FP-light and you're encouraged to return a null/error value from the intermediate calculation instead of doing an early return from the outer scope. It's a nice and easy to follow way to structure the code IME. Yes, it's more verbose when an early return would have been just right - so be it.

For the case where `try` is useful over the functional form (i.e. parent's situation of having a desired Result, plus some unrelated early-returning), that ends up with nested `Result`s though, i.e. spamming an `Ok(Ok(x))` on all the non-erroring cases, which gets ugly fast.

Why couldnt you flatten it?

You have three different value cases (main value, main Err case for `?` to consume, and whatever early-return case). And the `?` operator fully taking up the Err result case means your main-result+early-return values strictly must both be wrapped in an Ok.

Wouldn't that also move any referenced variables too? Unlike the block example that would make this code not identical to what it's replacing.

No, unless you ask for it via the `move` keyword in front of the closure.

This works fine: https://play.rust-lang.org/?version=stable&mode=debug&editio...

My instinct is this would get hairy much faster if you want to actually close over variables compared to using a block.

Not sure if that is relevant to your point, but: For better and for worse, closing over any outer scope variables is syntactically free in Rust lambdas. You just access them.

It's syntactically free, but it can cause borrow-checker errors thst cause your code to outright fail to compile.

Yes, exactly. My concerns were semantic, not syntactic.

If the verbose return type syntax can't be elided, I think it's more or less dead as a pattern.