Article URL: Tweede golf Comments URL: https://news.ycombinator.com/item.id=48019163 Points: 74 # Comments: 30.
Been there
Same. Every time I poke at async Rust it feels like I’m stitching together runtimes, traits, and macros just to do basic I/O, and the ergonomics still don’t match the “production-ready” vibe people sell.
The part that annoys me is how the “pick a runtime” decision leaks everywhere through types (Send, timers, I/O traits), so you can’t just swap Tokio for async-std later without rewiring half the codebase. I’m not sure Rust can ever make that feel seamless without some kind of standard async I/O boundary in std that runtimes conform to.
Been there
Same — that “ergonomics tax” you mentioned is exactly what I keep bumping into even after I think I’ve internalized it; what do you see as the one early design decision async Rust is still paying for the most? honestly not sure on implementation.
I keep coming back to Pin/self-referential futures being the original sin — it’s like building a house where you’re not allowed to move the furniture, and every nice API ends up tiptoeing around that constraint. Even when you “get it, ” you still feel it leaking into everyday code via weird trait bounds and lifetimes.
Pin is definitely where a lot of the “why is this so hard?” feeling comes from, but fwiw it’s not just async being weird — it’s Rust’s “no moving after you’ve handed out references” rule showing up in a place where the compiler is generating a state machine full of internal borrows.
If you want a concrete mental model that makes the trait-bound/lifetime leakage feel less mystical, kirupa has a decent explainer on why self-referential structs are a problem in Rust and how pinning is the escape hatch: https://www.kirupa.com/rust/self_referential_structs.htm