I was against this entire feature on two counts:
- The syntax - IMO ? isn’t something people would intuitivly associate specifically with error handling and I think both ? and ! are significant punctuation signs that could have been better utilized in Rust.
- Semantics - this is of course the main thing - I’m against adding ad-hoc special case syntax just for error handling. With that I agree whole-heartedly with @withoutboats above.
@glaebhoerl regarless of intent, there is relation to monads here becuase Result is a kind of monad. I think that this is the aspect we need to concentrate on. You once mentioned a very neat insight - Rust allows procedural code so in essence Rust code is already inside a sort of ambient Monad. This is why the alternative to this design - do-notation - had objections. How do we deal with control flow such as break, continue, loops, etc inside the do-notation?
This insight is key - do-notation wraps pure functional code into a monad but we are already inside an ambient monad so we actually need the reverse operator, an unwrap operator. This is what the ? should be IMO. This also has precedent in other languages (swift has something like that, i think).
This also relates to my other interest, stateless coroutines as proposed by Gor Nishanov for C++. In fact, I have posted here before a link to one of his presentations that shows that his await operator has the semantics of such an unwrap operator. More precisely:
fn f() -> M<T> {...}
fn g() {
let x = await f();
do_something_else(x);
}
await unwraps the T value out of the container M. If this operation “fails” than the control-flow is returned to the caller.
I think that Rust’s ? should be the exact same await, and the carrier trait is already almost the same as Gor’s Awaitable concept.