Live data from Hacker News

Why asynchronous Rust doesn't work

theta.eu.org

441–450 of 499 posts

Re: Why asynchronous Rust doesn't work

#441
post #163

Earlier quoted context omitted.

I and many others would disagree that they made the decision "at the expense of the long-term Rust health". You aren't arguing in good faith if you put words in their mouth. There is no data to suggest the long-term health of rust is at stake because of the years long path they took in stabilizing async today. There are merits to both models but nothing is as clear-cut as you make it to be - completion-based futures…

I do not put words in their mouth or have you missed the "in my opinion" part? The issues with Pin, problems around noalias, inability to design a proper async Drop solution, not a great compatibility with io-uring and IOCP. In my eyes they are indicators that Rust health in the async field has suffered. >Completion based is totally better and the only reason it wasn't done was because it would take too long and Rust…

I find your statements so strange. I honestly don't care about noalias, and very few people really should. Same with 'async drop'. Same with io-uring, which seems to be totally fine in Rust so far.

Despite your repeated statements that async has harmed Rust, I don't have any problem whatsoever day to day writing 10s of thousands of lines of async code with regards to what you've brought up.

Re: Why asynchronous Rust doesn't work

#442
post #183

Earlier quoted context omitted.

FWIW, I'd bet almost anything that this problem isn't solvable in any general way without linear types, at which point I bet it would be a somewhat easy modification to what Rust has already implemented. (Most of my development for a long time now has been in C++ using co_await with I/O completion and essentially all of the issues I run into--including the things analogous to "async Drop", which I would argue is actu…

> at which point I bet it would be a somewhat easy modification to what Rust has already implemented. You'd lose that bet: https://gankra.github.io/blah/linear-rust/

This is an article about why linear types are hard to implement... and it doesn't even claim they can't be done; regardless, I have argued this at you before :(.

https://news.ycombinator.com/item?id=23579426

I continue to believe that the strongest point in that article is actually the third footnote, which correctly admits that this is mostly about a lack of appreciation.

> The Swift devs have basically the exact same argument for move-only code, and their implicit Copy bound. Hooray!

My claim here is that, given linear types, it should be trivial to use async/await style coroutines for I/O continuation. You have given no evidence against this idea.

Re: Why asynchronous Rust doesn't work

#443
post #433
post #417

Earlier quoted context omitted.

I skimmed some of this, but are you asking why you need to clone in the closure? Because "async closures" don't exist at the moment, the closest you can get is a closure that returns a future, this usually has the form: where F: Fn() -> Fut, Fut: Future i.e. you call some closure f that returns a future that you can then await on. when writing that out it will look like: || { // closure async move { // returned futur…

Wait so you're saying "|| async move {}" is equivalent to "|| move { async move {} }"? If so then mystery solved, but that is not obvious at all and should be documented somewhere more clearly. In that case all I'm doing vs. their example is explicitly writing the function that returns the promise instead of letting it be "inferred?"

Well, no, that second one isn't valid rust, perhaps you mean:

   move || async move {} 
But this is not equivalent to:

  || async move {}
crucially the closure is not going to take ownership of anything. This is kind of besides the point though, what I'm getting at is that both of the above are a closure which returns a future. i.e. you can also write them in this style:

    || {
       return async move {};
    }
Maybe that's more clear with the explicit return?

I don't understand your second question about it begin "inferred", I never used that word. make_service_fn is a convenience function for implementing the Service trait.

Re: Why asynchronous Rust doesn't work

#444
post #430

Earlier quoted context omitted.

Cyclone wasn't backwards-compatible with C. ATS is not just "a blend of ML and C", it has a powerful proof system on top. You can't just say "well, these languages were derived from C in part, THEREFORE they must be easy to adopt at scale", that doesn't follow at all. Yes, Cyclone and ATS were research projects, that's why they were never able to accumulate the real-world experience needed to demonstrate that their i…

> Objective-C isn't memory safe. No, but it is garbage collected. > By "GC" here I meant memory reclamation schemes that require [...] object layout changes Changes with respect to what? One example of a popular GC is the boehm GC. It provides a drop-in replacement for malloc, usable in c for existing c structures without any ABI changes. Perhaps you are thinking specifically of compacting GCs, which usually need obj…

I have connections with the academic GC community. I gave an invited talk at ISMM 2012. I guarantee that they will not agree "Rust is a garbage-collected language".

FWIW Wikipedia describes "garbage collection" as "a form of automatic memory management" and goes on to say "Other similar techniques include stack allocation, region inference, memory ownership ..." so whoever wrote that doesn't agree that all forms of automatic reclamation are garbage collection.

I prefer to avoid arguing about the meaning of words but it's not good to sow confusion.

> Are the several multi-100-kloc ats compilers out there not real-world enough?

Yes, projects written by the creators of the language are not enough.

> If not then, on the topic of proof languages, ada/spark and isabelle/hol had proven themselves long before rust.

Before Rust, Ada/SPARK didn't support dynamic deallocation. See https://www.adacore.com/uploads/techPapers/Safe-Dynamic-Memo..., which cites Rust.

SeL4 required 200K lines of Isabelle/HOL proofs to verify 7.5K lines of C; that approach simply doesn't scale.

Re: Why asynchronous Rust doesn't work

#445
post #442

Earlier quoted context omitted.

> at which point I bet it would be a somewhat easy modification to what Rust has already implemented. You'd lose that bet: https://gankra.github.io/blah/linear-rust/

This is an article about why linear types are hard to implement... and it doesn't even claim they can't be done; regardless, I have argued this at you before :(. https://news.ycombinator.com/item?id=23579426 I continue to believe that the strongest point in that article is actually the third footnote, which correctly admits that this is mostly about a lack of appreciation. > The Swift devs have basically the exact sa…

Ah! I misunderstood you, sorry. I thought you were saying that linear types would be easy to implement. I wasn't trying to say anything about the stuff you'd do with them if you had them.

Re: Why asynchronous Rust doesn't work

#446

I'm not totally sure what the author is asking for, apart from refcounting and heap allocations that happen behind your back. In my experience async Rust is heavily characterised by tasks (Futures) which own their data. They have to - when you spawn it, you're offloading ownership of its state to an executor that will keep it alive for some period of time that is out of the spawning code's control. That means all dat…

I'm a giant Rust fanboy and have been since about 2016. So, for context, this was literally before Futures existed in Rust. But, I only work on Rust code sporadically, so I definitely feel the pros and cons of it when I switch back and forth to/from Rust and other languages. The problem, IMO, isn't about allocations or ownership. In fact, I think that a lot of the complaints about async Rust aren't even about async R…

also a long-time rust user, and I buy this. one of the things it took me longest to realize when writing rust is to reach for traits carefully/reluctantly. they can be amazing (e.g. serde), but I've wasted tons of time trying to make some elegant trait system work when I could have solved the problem much more quickly otherwise.

Re: Why asynchronous Rust doesn't work

#448
post #172

Earlier quoted context omitted.

I don't see async/await (at least when built on top of futures/promises) as a procedural thing - the parts of C# where it's used are the least procedural parts of C#, and Python has always been multi-paradigm. I'd say it's mainly a way of doing monadic futures in languages that don't have monads (mainly because of lacking HKT) - hence why F# adopted it first, and then it made its way into functional-friendly language…

Sure. What I'm getting at is that I see the specific syntax of "async-await" as a synthesis of concepts from functional and procedural heritage. I agree about it being a spectrum and all that, so I think we're mostly just talking past each other about the specifics of how it came to be and using different ways of describing that process.

What procedural heritage do they have? I don't think there's anything procedural about them (unless you consider "doesn't have HKT" to be the same as "procedural").

Re: Why asynchronous Rust doesn't work

#449
post #412

Earlier quoted context omitted.

> I am not sure whether this is actually viable. Having investigated this myself, I would be very surprised to discover that it is. The only viable solution to make AsyncRead zero cost for io-uring would be to have required futures to be polled to completion before they are dropped. So you can give up on select and most necessary concurrency primitives. You really want to be able to stop running futures you don't nee…

Well, you can still have select; it "just" has to react to one of the futures becoming ready by cancelling all the other ones and waiting (asynchronously) for the cancellation to be complete. Future doesn't currently have a "cancel" method, but I guess it would just be represented as async drop. So this requires some way of enforcing that async drop is called, which is hard, but I believe it's equally hard as enforci…

> Well, you can still have select; it "just" has to react to one of the futures becoming ready by cancelling all the other ones and waiting (asynchronously) for the cancellation to be complete.

Right. Which is more or less what the structured concurrency primitives in Kotlin, Trio, and soon Swift are doing.

Re: Why asynchronous Rust doesn't work

#450

A bigger problem in my opinion is that Rust has chosen to follow the poll-based model (you can say that it was effectively designed around epoll), while the completion-based one (e.g. io-uring and IOCP) with high probability will be the way of doing async in future (especially in the light of Spectre and Meltdown). Instead of carefully weighing advantages and disadvantages of both models, the decision was effectively…

I think there are 2 separate findings in it:

First of all yes, Rust futures use a poll model, where any state changes from different tasks don't directly call completions, but instead just schedule the original task to wake up again. I still think this is a good fit, and makes a lot of sense. It avoids a lot of errors on having a variety of state on the call stack before calling the continuation, which then gets invalidated. The model by itself also doesn't automatically make using completion based IO impossible.

However the polling model in Rust is combined with the model of always being able to drop a Future in order to cancel a task. This doesn't allow to use lower level libraries which require to do this without applying any additional workarounds.

However that part of Rusts model could be enhanced if there is enough interest in it. e.g. [1] discusses a proposal for it.

[1] https://rust-lang.zulipchat.com/#narrow/stream/187312-wg-asy...

Post reply on HN