Replace async/await with built-in state machine syntax

this isn’t a pre-rfc or anything I just think it’d make more sense to have explicit state-machine syntax (maybe with a macro) instead of async/await. this gives you more control and state machines are awesome and that’s plenty of reason to use them!

No, the point of async/await is not the state machine. You can do that manually already using enums and a function. The point is ergonomics. Which wouldn’t really be solved by some state machine syntax.

9 Likes

I find state machines more ergonomic because you use goto everywhere i.e. explicit flow control.

(True coroutines are ergonomic because you don’t have to think about it.)

1 Like

The majority of the ergonomics of async/await come from safe self-referencing, if you have concrete syntax proposals for how to provide safe self-referencing ergonomically in a builtin state machine syntax that could be an alternative proposal to async/await, but at this point it’s a little late to really talk about replacing async/await with an undesigned alternative.

18 Likes

we could just develop an alternative and later deprecate the existing thing.

I propose it be declarative with imperative procedures. I feel like declarative is better for “asynchronous”/“non-linear” stuff but you still want imperative to adjust/process the data before handing it out to the next step in the pipeline.

As I said before, you can already make an efficient state machine in Rust today.

let mut state = init_state;

loop {
    match state {
        State::Variant1 => { do_work_for_1() },
        State::Variant2 => { do_work_for_2() },
        State::Variant3 => { do_work_for_3() },
        ...
    }
}

In fact there are lots of crates that streamline this process already,

https://crates.io/search?page=2&q=state%20machine


Not really an option for such a large part of the language

What do you mean by this, it’s not at all clear

2 Likes

SQL with native functions extension?

for real tho we can just create new editions whenever we feel like it.

rust 2020 edition should be called “hindsight edition” and introduce a declarative DSL (think SQL, but for network/async instead of DBs) with the ability to call imperative (normal rust) functions. but defined so that the behaviour isn’t surprising with a bunch of unnecessary and unexpected calls to the rust functions and stuff. nobody likes that part of SQL.

I mean in an ideal world I’d just encode everything in the type system and be done with it. but w/e.

some other languages seem to do quite well with the A/B testing/“try it and see” model. consider: https://github.com/arclanguage/anarki

anyone willing to make/implement an alternative to async/await, flesh it out a little, etc with me?

I think this is a good idea, but it may be better as an external addition, or in a different language?

A DSL for async could be super interesting if implemented as a proc-macro which then compiled down to an async fn or to a state machine.

The reason I would object to replacing async/await with this is that it doesn't seem like it'd give a lot of manual control to users. One of the big advantages of rust is how much we can tune things, and DSLs like SQL, while super ergonomic, are not known for allowing manual optimization.


If you're seriously wanting to do this though, have you thought about implementing it as a crate?

You could brainstorm syntax, write something usable, and get feedback - and that'd put the proposal in a much better position if it were to be included in rustc in the future. async/await needed core language support because it has self-referential borrowing and borrow checking which can be much, much more easily done in-compiler than externally. I don't think a DSL would have the same problems - it should be able to work as an external addition.

I mean even async fn started out as an experimental external crate (without borrowing support, if I recall correctly) before being added to rustc. It's a great way to prototype.

4 Likes