Hacker News new | past | comments | ask | show | jobs | submit login
Was Async Fn a Mistake? (seanmonstar.com)
40 points by MrBuddyCasino 7 months ago | hide | past | favorite | 11 comments



I'm a bit of a broken record, but I will summarize my experience as someone who builds a lot of Rust web services as:

1. My overall experience with async is very positive

2. There are tricky bits where even I, an experience borrow check wrestler, don't know what to do - I just refactor the code to avoid the issue in these cases. This is not a very common situation, it has only occurred in 'free time' code where I'm trying to really optimize my code.

3. I am overall very optimistic about the future of async in Rust, even if today it requires some onboarding time.

I'm excited for things to improve. There are ergonomics wins coming soon like async in traits, there are improved compiler diagnostics, expansions of what can be done (to address my 'zero copy' use cases), etc.

Perhaps it's bikeshedding but I hate the `= async` quite a lot.

I'm curious to see how things develop from here in the next 3-5 years, as I imagine we'll see some significant improvements to the existing system.


For me Rust (after initial euphoria around 1.0 release) became the best option to do some heavy duty routines, like crunching through complicated large XML or calculating exotic things (that I can't bother to modify to run on a GPU). Basically synchronous CPU intense tasks. Thats kinda the sweet spot overall for me after the years. Completely gave up on using it for anything else.

When I want concurrency/parallelism/distribution, just use the BEAM (iE: Elixir) which is literally made for that problem space. BEAM is not exactly good for computations, though (as are many other tech stacks)... so writing a native extension/library in Rust when there really is a demand is perfect - but any scheduling whatsoever stays in BEAM territory, including keeping an eye on the non-preemptive behavior of the Rust function and schedule calls to it properly.

So for me, I don't need async (or even multicore) rust anymore to begin with, but the base functionality of the language (especially including serde!) knocks it out of the park for some problems like nothing else.


Personally, I figure everything "await"ed by default seems to make more sense. Then add a keyword like "delay"ed to a function call to make the function return a promise that can be "await"ed later.

This way beginners don't have to understand things like the event loop or difference between a function that returns a promise and one that doesn't while more advanced users can still manually handle promises


It's too late to remove async fn, but can we still implement his "What if the alternative was nicer"? Is there any good reason why I can't use await in a non-async function that returns a Future?


I kind of wish the calling convention for async didn't have await at all. What if instead of a special syntax for waiting on an async function you instead had a special syntax for _not_ awaiting. If you want a copy of the future then there is an alternate syntax.

What I really want is for my synchronous and asynchronous code to be a lot more transparent and not force my hand depending on whether I'm calling from a synchronous or asynchronous context. I know this is a really difficult ask because of the lack of knowledge of what runtime to use when calling an async task in the context of a synchronous call...

Its the coloring problem I ultimately hate fighting against. There are definitely times that I care about it, long running blocking synchronous calls and getting a handle on a Future are really the only ones I can think of and they tend to be the exception not the norm.


Very fair, but if Rust gets a great effects system I think that'll be even better. Will take a while, though.


I suspect there are enough performance differences and small semantic gotchas in functions that can be suspended and restarted without burning a kernel thread to make that undesirable.


the main problem is that there needs to be someone in charge of waking up your thread when it's ready, and also to run it. in your case you don't need the run part. But the waking part is tied to what the future is: a busy polling loop, a sleeping select, an io_uring; in fact it can be anything. You can manually make a future that returns immediately or sleeps forever. The rest of your code has no way to know these implementation details.


> It's too late to remove async fn, but can we still implement his "What if the alternative was nicer"?

I think that "Ability to forgo naming an associated type name." seems very reasonable to me

> Is there any good reason why I can't use await in a non-async function that returns a Future?

You can do this afaik


I think you have to use something like the "pollster" crate, which is an async runtime that just pauses the thread until the future is ready.


`block_on` should do that, as should local task sets, but that's not necessary afaik - you can just poll it normally




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: