This is a beautiful approach, but still has a problem: at any point, you can drop the value, even if that might not be legal in the protocol.
In other terms, Rusts type system does not support denying to exit the protocol chain at any place. This introduces another implicit additional state.
There were suggestions for adding linear types to Rust: https://internals.rust-lang.org/t/pre-rfc-linear-types-take-2/1323
I would really like to see this happening, as for some cases (e.g. files), I would prefer explicit removal/closing over manual but would enjoy the compiler to enforce that.
Linear types are types that must be consumed once, while Rusts types only can be consumed at most once (or dropped).
For most kinds of stateful communication, the connection can be dropped without warning anyway - cable cut, router outage, even within the same machine one party might accidentally divide by zero or get killed by the OOM-killer. There might even be a power-outage.
So robust systems already need to handle unexpected terminations; Rust’s ability to drop things (or leak things) doesn’t make the problem much worse.
I didn’t want to imply that it’s worse, just that this is a caveat to be aware of. (even in Rust with linear types, Rust still has panic!)
But compiler enforcement to make sure that a state machine, once started, is brought to an end state in all cases is really useful.
Can’t you do that with destructors in rust?
You can implement it with destructors, but the compiler cannot guarantee that all states terminate correctly, that is up to the programmer writing those destructors to enforce.
This would be called a destructor bomb and is possible, but it needs running the code (all paths, to be exact).
I, for one, welcome our new functional overlords. :-)