Remix.run Logo
loeg 2 days ago

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>()?)
    })();
rendaw 2 days ago | parent | next [-]

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.

ahartmetz 2 days ago | parent [-]

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.

dzaima 2 days ago | parent [-]

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.

skribanto 2 days ago | parent [-]

Why couldnt you flatten it?

dzaima 13 hours ago | parent [-]

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.

schneems 2 days ago | parent | prev | next [-]

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.

pflanze 2 days ago | parent [-]

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...

saghm 2 days ago | parent | prev [-]

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

ahartmetz 2 days ago | parent | next [-]

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.

nicoburns 2 days ago | parent [-]

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

saghm 2 days ago | parent [-]

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

loeg 2 days ago | parent | prev [-]

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