upvote
I would also have liked to see some motivational examples, but I think the most interesting upside of an effect system is composability.

Rust is actually really unique among imperative languages in its general composability - things just compose really well across most language features.

The big missing pieces for composability are higher-kinded types (where you could be generic over Option, Result, etc.), and effects (where you could be generic over async-fn, const-fn, hypothetical nopanic-fn, etc.)

The former becomes obvious with the amount of interface duplication between types like Option and Result. The latter becomes obvious with the number of variants of certain functions that essentially do the same thing but with a different color.

reply
Not so much composability on async Rust.
reply
Some uses of higher-kinded types (though not all of them) can be addressed by leveraging Generic Associated Types (GAT).

Part of the problems is that the "things just compose really well" point becomes gradually less and less applicable as you involve the lower-level features Rust must be concerned with. Abstractions start to become very leaky and it's not clear how best to patch things up without a large increase in complexity. A lot of foundational PL research is needed to address this sensibly.

reply
"View types" addresses one of the top pain points of the borrow checker, which is disjoint borrows on a single value. The compiler can understand values where only some fields are borrowed, so e.g. you can mutably borrow the currently-unborrowed fields, but there's no way to write these partial borrows and so you cannot write functions that either take or return these borrows. This often means having to restructure code to split up one struct into several child structs just to be able to borrow those substructs independently.
reply