Live data from Hacker News

Why asynchronous Rust doesn't work

eta.st

241–250 of 305 posts

Re: Why asynchronous Rust doesn't work

#241
post #199

"Maybe we could just have kept Rust as it was circa 2016, and let the crazy non-blocking folks write hand-crafted epoll() loops like they do in C++. I honestly don’t know, and think it’s a difficult problem to solve." I think this is the most underappreciated part of this article. Since when did everything have to be async? There are other ways to represent concurrency that more accurately reflect what the computer i…

> let the crazy non-blocking folks write hand-crafted epoll() loops like they do in C++. > I think this is the most underappreciated part of this article. I think it's incredibly silly actually. Abandon all async for a difficult and error prone epoll model? > Since when did everything have to be async? It doesn't! No one is forcing anyone to use async. I'm not sure why the author implies that. But if you do want to u…

>It doesn't! No one is forcing anyone to use async.

Well, hang on there... this isn't entirely fair.

Rust does not force you to be async, but the community in some ways pushes you to be async even where it might not make sense for it to be the default. I can't say for certain (and this is all my opinion, to be clear) but it feels like this started happening when async-fervor hit its peak.

My go-to example is reqwest, which if you want a blocking HTTP call, still just needs all of Tokio in the background. I find it really odd that the blocking API is just a wrapper for a finagled async API; if I'm choosing the blocking one, I probably don't want Tokio in my project.

There are other HTTP request libraries, to be clear - but they're often less battle tested and/or have their own lurking bugs. Reqwest is the de-facto one and it'd be nice to be able to use it without the heaviness it brings in.

Depending on the domain you're programming in, it can often feel like async-by-default is the norm. It can be frustrating in Rust.

(It's nowhere near enough to deter me from using the language, mind you)

Re: Why asynchronous Rust doesn't work

#242
So basically, Rust does async right, but the author wishes he didn't have to worry about generics and lifetime management which become increasingly complicated in asynchronous contexts.

Maybe this guy needs to just stick to Lisp.

Re: Why asynchronous Rust doesn't work

#243
post #7

The article glosses over async Rust and is mostly a rant about how closures are difficult in Rust. Most of the difficulty comes from Rust not having a GC yet wishing to keep track of object lifetimes precisely: a GC'ed language needs no distinction between an ordinary function pointer and a closure that captures the environment. But Rust being a low-level systems language chose not to have a GC. Another popular langu…

From my very limited expeirience with Rust I noticed that it becomes way more easy and laid back language when you just skip using references and lifetimes nearly completely and just wrap everything in Rc . Then you are getting expeirience of fairly high level language with a lot of very cool constructs and features like exhaustive pattern matching and value types with a lot of auto-derived functionality. Does Rc hel…

Reference counting is mostly a cop-out for people who can't design code properly and reason about ownership and lifetimes.

It essentially makes your code Java and defeats the point of the language.

I would expect most decent teams to reject your code during code reviews.

Re: Why asynchronous Rust doesn't work

#244
post #15

It was heavily discussed previously. In particular, it triggered this response from Rust contributor withoutboats: https://news.ycombinator.com/item?id=26410487 And this blog post from someone who did spend a lot of time working with async rust: https://tomaka.medium.com/a-look-back-at-asynchronous-rust-d...

Is that provoked by the author of this post, or just a random commenter on the thread that post spawned? It looks like the latter.

I’d say both. The author of the post called Rust async/await a disaster, and the top commenter, who withoutboats replied to, agreed with the author’s criticism.

Re: Why asynchronous Rust doesn't work

#245
post #176
post #160

Earlier quoted context omitted.

C++ lambdas need that feature because they don't have lifetimes or a borrow checker. Rust closures don't need that feature because rust has a borrow checker that ensures you aren't referencing something you shouldn't be. You can explicitly decide what to copy inside a Rust closure as well, you just use a `move` closure and create references for anything you need referenced outside the closure instead.

Move closures assume everything is movable, in C++ you can control what actually takes place, and yes there is the possibility to get it wrong.

Parent is saying that you can declare your closure 'move' and move references rather than values, therefore getting the mixed behavior you described. You don't have to move all values.

Re: Why asynchronous Rust doesn't work

#246

Earlier quoted context omitted.

`Rc` freezes the value as long as it's shared unless you use interior mutability. It's fine when you want to share immutable data, but if you ever need to mutate its contents you will have to deal with awkward cases and situations, and at runtime! Wrapping everything in `Rc` is not a good default strategy. Instead figure out an architecture that works well with the borrow checker! This normally means thinking hard ab…

Are there any good resources for design patterns in Rust? I've gone through Rust by example and am writing mid-size rust programs now but would love to check my work against the experts.

Rust also just enforces good C++ practices, so you could just get yourself familiar with the 40 years history of C++.

Re: Why asynchronous Rust doesn't work

#247

Earlier quoted context omitted.

Exceptions are a mechanism for error handling that comes with control flow changes. But Rust already has perfectly nice control flow mechanisms (look at std::ops::ControlFlow for example) and perfectly nice error handling. So you can use either, or both, as necessary, you don't need this particular Frankenstein's Monster. Using Exceptions for things that aren't actually exceptional is perverse.

> Using Exceptions for things that aren't actually exceptional is perverse. In python using exceptions for some control flow is actually accepted practice if you don't go overboard. I think it's better that way because it turns them into something familiar instead of pushing them back to some extraordinary circumstances. The thing that C++ does with exception means that programmers mind is encouraged to stay on happy…

That is precisely what C++ does.

Re: Why asynchronous Rust doesn't work

#248

Earlier quoted context omitted.

Not possible for the same reasons why just adding a borrow checker to C++ isn't possible. Mostly this comes down to incompatibility with existing code. Zig is just not memory safe, and the only solution would be to add a GC.

If you don't consider Swift style Automatic Reference Counting a GC, then there is another option.

That's a form of garbage collection. :)

Re: Why asynchronous Rust doesn't work

#249

Earlier quoted context omitted.

I don't think base + offset would have worked because then references would have to be codegen'd differently depending on whether they're in a future or not; this would have impacted separate compilation as you can pass references to other functions (including across FFI). Relocations only work at load time (either dynamic linking or link time), so they wouldn't work. Limiting what can be captured was tried with the…

"Relocations" was meant as an analogy. The idea is, each time a future is entered, it checks if its base pointer has changed. If so, it fixes up its own pointers, similar to how a linker fixes up self-pointers in a dynamic library. There's obvious limitations but it would handle common cases efficiently. Anyways when I first tried async, I encountered structural pinning immediately, and I was surprised to learn that…

I don't think it's possible for a future to enumerate all the references that belong to it. At the very least it's not obvious to me how that's possible to implement, due to the way lifetime subtyping works.

Re: Why asynchronous Rust doesn't work

#250
post #15

It was heavily discussed previously. In particular, it triggered this response from Rust contributor withoutboats: https://news.ycombinator.com/item?id=26410487 And this blog post from someone who did spend a lot of time working with async rust: https://tomaka.medium.com/a-look-back-at-asynchronous-rust-d...

Oh, thanks for that link. Withoutboats is being quite emotional, but it is understandable to be emotional about their brain child. I am tempted from time to time to try Rust, but in the end, I don't think it provides enough benefits for me to consider it. I like high-level, and when I am going low-level, I don't want to be hand-cuffed. It seems with Rust, I am paying all the time just for the ability to go into hand-…

The point of Rust is that your mediocre C++ developers won't be able to write some kinds of bad code patterns with it, since it won't compile.

The problem is that most likely those mediocre C++ developers won't be able to write any Rust at all.

If you do have good C++ developers, you're also probably better off sticking to well-established and battle-proven C++.

So the use case for Rust remains niche. It's a way to attract the programming language nerd that knows more about Haskell than he does about systems programming. Maybe not exactly the best fit? But worth trying if you want to differentiate yourself from the competition.

Post reply on HN