[Pre-RFC]: Unifying the ? operator and and_then


#1

I’m new to rust so maybe my idea has been proposed before but I didn’t find anything about it so I’m posting it here for discussion:

The ? operator is very useful but it seems like it could apply not just to Result but also to Option and many other types. Actually I think it should apply to every type that implements and_then (including the futures everyone is talking about). I think that

let x = y?;
z

should be syntactic sugar for

y.and_then(|x| {z});

This is already the behavior of ? so it wouldn’t break existing code.

I understand that such a change wouldn’t be easy because the z of my example may not be easy to isolate and lifetimes can end before the end of the enclosing function but I think these challenges could be overcome.

Was this discussed before and are there good reasons not to do it?


#2

This RFC was one of the most-discussed in history; the catch part of it is kind of like a series of and_thens.

Here’s the thread in its full glory: https://github.com/rust-lang/rfcs/pull/243


#3

There are two separate things:

First, making ? an overloadable operator controlled by a trait is already in the works.

Second, and_then does not behave the same as ?. ? will early return, whereas and_then will not.


#4

The RFC thread answered most of my questions, thanks.

@withoutboats I disagree, If you put everything that comes after ? in the and_then, there is no such thing as early or late return. As soon as the and_then returns, the whole function returns because there is nothing after it.


#5

If the ? is in a loop, or one branch of a conditional, or otherwise nested in a larger expression, it may not be so simple to transform the function such that “everything that comes after” is in the and_then closure.


#6

I wish it was that simple but it isn’t. :frowning: If it was then your sort of larger goal would be correct, we could use ? to make async code look like straightforward blocking code.


#7

The async/await monad unwrappers that are available in C#, Javascript, and Scala (via a compiler plugin) are one way to make usage of monads like Option and Future look like sequential code.

As mentioned though, I don’t know if there is any support for usage of those transforms in the context of loops.