Live data from Hacker News

Why asynchronous Rust doesn't work

theta.eu.org

301–310 of 499 posts

Re: Why asynchronous Rust doesn't work

#301

Can we please stop using this "color" argument to Rust? The original colouring article was about JavaScript, a dynamically typed language. But rust is a statically typed language, and in a sense, the type is the colour. You can't return an error from a function that does not return a Result . And most people agree it is a great thing over dynamic/implicit exceptions. Declaring a function just changes the return type…

Also Rust async runtimes have `block_on(async)` and `spawn_blocking(sync).await`, so the main problem of call graphs split by "color" doesn't exist in Rust. Rust can merge the two worlds.

Unlike JS, Rust can wait for async code in blocking contexts, and it can run CPU-bound code in async contexts.

Re: Why asynchronous Rust doesn't work

#302
post #50

Earlier quoted context omitted.

It is in no danger of become as complex than C++. Nowhere near.

Traits, generics, lifetimes, macros and endless, and incomprehensible backtraces when using Futures already makes it more complex. Rust is difficult to read and maintain, due to the common use of abstractions over abstractions over abstractions. Just looking at a structure, it’s already hard to understand what functions are available (hidden in traits, themselves behaving different according to cargo features…). And…

The fact that Rust has traits and generics doesn't make it more complex than C++, because they substitute for C++ features that are even more complex (classes, virtual methods, templates, concepts).

I believe C++ is far more complex because, having programmed in C++ for 30 years and hanging out with other developers with similar levels of experience, I still trip over weird C++ features that I never knew existed. My latest example: Argument Dependent Lookup, which means f(a) and (f)(a) can wind up calling completely different functions. How many C++ developers know that?

In my experience, Rust has fewer complexities like that.

Re: Why asynchronous Rust doesn't work

#303

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…

This post is completely and totally wrong. At least you got to ruin my day, I hope that's a consolation prize for you. There is NO meaningful connection between the completion vs polling futures model and the epoll vs io-uring IO models. comex's comments regarding this fact are mostly accurate. The polling model that Rust chose is the only approach that has been able to achieve single allocation state machines in Rus…

Is it just me or you're supporting your parent's point of:

> ...the decision was effectively made on the ground of "we want to ship async support as soon as possible" [1].

When you write:

> Moreover, getting a usable async/await MVP was absolutely essential to getting Rust the escape velocity to survive the ejection from Mozilla...

This whole situation saddens me. I wish Mozilla could have given you guys more breathing room to work on such critical parts. Regardless, thank you for your dedication.

Re: Why asynchronous Rust doesn't work

#304

If Rust had to be rewritten from scratch today, it would probably be done differently, learning from experience since it was invented. Cargo, macros, const generics and `#[cfg]` wouldn’t exist any more, replaced with comptime evaluation. The standard library would be half its current size (considering its redundant functions, deprecated functions, or constructions that Clippy wants to be replaced with other construct…

I see you're a fan of Zig's design, but I don't really think Rust would be as you describe even if it was made today, for several reasons: - comptime evaluation aren't something Rust designers are interested in, as it doesn't fit their functional programming mindset[1], (and it's not a new concept to Zig, D has had something similar for long). - An IDE-first compiler is a good idea (and a must have for a production l…

rust-analyzer is remarkably good.

I am curious as to how Zig comptime is going to interact with IDE features.

Re: Why asynchronous Rust doesn't work

#305
post #10

Earlier quoted context omitted.

What's an alternative to async/await that's explicit about runtime costs?

How explicit do you want? The loom model is VM managed thread stacks with user space context switching. The costs are all quantifiable and a suspended "virtual" thread uses memory directly proportional to the amount of stuff on the stack, same as any coro implementation. However there is no async/await or coloured functions. The VM just makes threads super cheap

Rust started off with user ("green") threads. The problem is interop with other code via FFI --- it gets really painful and potentially expensive. That's not good for a systems language. So they ripped it out.

Re: Why asynchronous Rust doesn't work

#306

Funny how the Rust community used to regard JavaScript with contempt. Yet now when you consider how well JS was able to add support for asynchronous programming, it's pretty clear that JavaScript was actually a great programming language all along. JavaScript was designed to evolve. That's the difference between intelligence and wisdom. Unlike intelligence, wisdom takes into account the unknown.

The Rust community regards the JS community with contempt? Where does that opinion come from?

Re: Why asynchronous Rust doesn't work

#307

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…

This post is completely and totally wrong. At least you got to ruin my day, I hope that's a consolation prize for you. There is NO meaningful connection between the completion vs polling futures model and the epoll vs io-uring IO models. comex's comments regarding this fact are mostly accurate. The polling model that Rust chose is the only approach that has been able to achieve single allocation state machines in Rus…

You are awesome. Thank you for clarifying these things.

Re: Why asynchronous Rust doesn't work

#308

Earlier quoted context omitted.

He's just pointing out that it isn't very ergonomic, not that Rust is bad (in fact he states the opposite multiple times). Pointing out weaknesses and things that might be done better is what helps something mature, not just praising it.

"Ergonomic" is such a nebulous word as to be nearly useless honestly. I don't see how it is [unduly] inefficient or uncomfortable for a language at Rust's level to ensure that the programmer actually thinks through the execution of the code they are writing. If one doesn't want to think about such things - and there's absolutely nothing wrong with that! - there are plenty of higher level languages that can do that le…

The whole point of async is entirely ergonomics. Anything you can do in async you can do in continuation-passing style.

I believe the point the author is making is that they added a feature for ergonomics' sake that ended up not being ergonomic; async-style programming usually coincides with first-class functions and closures, and those are painful in Rust.

Re: Why asynchronous Rust doesn't work

#310

Again, feeling old, I'm not seeing a lot wrong with threads. A thread pool, if you insist, but explicit workflows as opposed to chaining together callbacks and contexts ... just seems really easy.

Things that are easier with Rust's async:

• Timeouts and cancellation. Rust's async code can be aborted from the outside (with correct cancellation and cleanup of everything in progress). OTOH if you run imperative blocking code, you need every blocking function to cooperate.

• Full utilization of CPU and I/O in workloads that mix both. Async executor balances threadpools/polling queues for these automatically. OTOH if you just use regular blocking calls with no state machines/continuations, it will be hard to separate these two. A single mixed-use threadpool will oscillate between I/O-bound threads and underutilizing CPU, and CPU-bound threads and idling I/O.

Post reply on HN