@jbz as a Rust enthusiast I mostly agree with this post.
I'll add another downside: due to the friggin' orphan rule it's impossible to extend a dependency's functionality without forking it (e.g.: you can't add additional derives to a foreign crate's types).

Re async, it's often made extra hard because the default (language!) assumption is multithreading. Thread-local async can make it much more pleasant, as outlined here: https://maciej.codes/2022-06-09-local-async.html

Local Async Executors and Why They Should be the Default

@dngrs @jbz there is no default language towards multi thread because async does not prescribe how to poll and wake up futures. The perceived default comes from Tokio being used everywhere for everything even though the futures crate would suffice.

About the post: it's typical shill from the dude that tries to generate clicks by being controversial.

@matze @jbz std::task::Waker is Sync
(edit: arguably a stdlib, not language level issue)
@dngrs @jbz and? That enables multi threaded executors but does not require futures to be Send and Sync. It's when you tokio::task::spawn a future that all of a sudden the future must implement those.
@matze @jbz yes, obviously thread local executors are a thing, I literally linked a blog post about them (and tokio itself has LocalSet, too), but arguably these assumptions (Waker being Sync, Wake taking an Arc) influence the way crates/ecosystems are designed; iirc it also bleeds into manual Future implementations because poll takes a Context which essentially is a Waker. but I see there's now a nightly api for local_waker() so that's something to look forward to