Live data from Hacker News

Zero-cost futures in Rust

aturon.github.io

191–200 of 348 posts

Re: Zero-cost futures in Rust

#191

Finally a nice async/io interface for rust, always felt that it was a big missing piece, couple of questions for peps familiar with async in other languages : 1 - Isn't the state machine approach the same as C#/.net async/await is using ? But the with the added convenience of the syntactic sugar ? 2 - no allocation : , does'nt the lambda closure need to be allocated somewhere ? 3 - I would have love some comparison (…

C++ programmer here; re 3: the C++ coroutine proposals (there are multiple) are completely orthogonal to futures. The closest things in the standard to these rust futures, is of course std::future, which currently is very limited as it even lacks chaining and composition. The Concurrency TR (which eventually will be added to the standard, but sadly not for C++17) does provide these features (and more); multiple imple…

Thanks your answer clarifies a lot. So my question was , as a mechanism to implement async operation how does C++ coroutine compares to this rust library. From my understanding the C++ committee is pushing for the introduction of coroutine specifically because any library base approach would have the limitation you mentioned. Is that a correct ?

You seems familiar with the C++ committee, do you know a good way to track a feature one is interested in ? I kinda lost track of the coroutine proposal after the 4 revision or Gor paper.

By the beside Visual studio, any other compiler has a working implementation of the current draft ?

Re: Zero-cost futures in Rust

#192

Earlier quoted context omitted.

> You can recover most of the M:N ergonomics over time via async/await style syntax. While i agree with the tradeoff made by rust (although i think the approach used by C++ coroutine is better), i don't think that having async/await syntax give you "most" of the ergonomics of the Go M:N model . The main advantage of the go model is that both asynchronous and synchronous operations are identical, with async/await you…

> although i think the approach used by C++ coroutine is better How? > The main advantage of the go model is that both asynchronous and synchronous operations are identical, with async/await you still need to model the async operation and the sync operation with different types. It's more like "everything is synchronous" in the Go model. Semantically, Go doesn't have async I/O at all. It has a userspace M:N implement…

Defaults matter. If some people use async I/O and others don't then you get a mess when they want to share reusable libraries. It's similar to the mess you get when there is more than one string type.

I think the "what color is your function" problem could be mostly solved by making async/await the default function type - that is, most callback functions should be allowed to suspend execution by waiting on a Future.

Then you could have special-purpose "atomic" functions that are occasionally useful for pure functional code.

(Unfortunately, the default has to be the opposite in browser-based languages due to performance concerns.)

Re: Zero-cost futures in Rust

#193

Earlier quoted context omitted.

Except when the IO doesn't go though the kernel in the first place of course.

What I/O doesn't go through the kernel?

For the example if you are using kernel bypass of the network stack, which is increasingly common in high throughput/low latency applications.

Re: Zero-cost futures in Rust

#194

Big downside is now you will have a dichotomy of functions that block using futures and functions that block at the OS level and no sane way to intermix them. Rust essentially becomes two languages. Async/await sugar doesn't fix this. Would be great if functions could be written in a general way for both IO models and users could select the implementation at their convenience.

> no sane way to intermix them. My understanding is, the idea is to put the blocking stuff in a threadpool with https://github.com/alexcrichton/futures-rs/tree/master/futur...

Right, there may be a lot of back and forth marshaling between using thread pools and not depending on whether the library you're using is futures based or not.

Maybe you use one library that is futures-based and one that isn't. Maybe the library you use is mostly non-blocking except for one use of sleep() or another esotorically blocking call. It's just annoying and prone to error. Most people may not even be aware of the subtly blocking nature of the code they use in their futures-based project.

This is what I mean by having two different languages. Libraries written for one aren't always/simply compatible with the other. You'll have a growing community of nominally "futures-based" rust libraries too.

This is why people use Go or Erlang. It just removes the need to have to think about this. Not saying they are generally better than Rust, and some Rust people may even like having a futures-based sublanguage, but I suspect most programmers will be loathe to have to deal with the extra mental tax.

Re: Zero-cost futures in Rust

#195

Earlier quoted context omitted.

> Being able to express your code in a sequential manor and still gain the performance offered by implicit fiber,goroutine,w/e scheduling is pretty awesome. You don't gain as much performance. On Linux, you don't actually gain that much if anything over 1:1 threading. Most of the benefits of goroutines actually comes from the small stacks, which don't have anything to do with M:N and 1:1 to begin with—they're a featu…

> Why would you write networking code in C in 2016, when there are better alternatives available (like this one)? Support for kernel bypass networking libraries like ibverbs, DPDK (has an old unmaintained Rust wrapper) and other IO kernel bypass libraries such as SPDK and IOAT. If Rust supported these libraries, I'd much prefer the future based Rust code to a massive event loop in C.

It's all open-source, this is an area that if it matters this much to you, you could help support. The Rust community is hugely welcoming to people coming on and helping.

Re: Zero-cost futures in Rust

#196

Earlier quoted context omitted.

> although i think the approach used by C++ coroutine is better How? > The main advantage of the go model is that both asynchronous and synchronous operations are identical, with async/await you still need to model the async operation and the sync operation with different types. It's more like "everything is synchronous" in the Go model. Semantically, Go doesn't have async I/O at all. It has a userspace M:N implement…

Defaults matter. If some people use async I/O and others don't then you get a mess when they want to share reusable libraries. It's similar to the mess you get when there is more than one string type. I think the "what color is your function" problem could be mostly solved by making async/await the default function type - that is, most callback functions should be allowed to suspend execution by waiting on a Future.…

> (Unfortunately, the default has to be the opposite in browser-based languages due to performance concerns.)

Also in Rust. Most apps that aren't servers don't want async I/O, and it causes a lot of problems when you need high-performance FFI. For example, in Servo async-everywhere would be a big problem for WebRender, which needs to be able to call OpenGL extremely quickly.

> Defaults matter. If some people use async I/O and others don't then you get a mess when they want to share reusable libraries. It's similar to the mess you get when there is more than one string type.

Given that having both is necessary for Rust (maybe a necessary evil), I think the right approach is to make jumping from one mode to the other painless. For sync-to-async, it needs to be easy to block on the result; for async-to-sync, it needs to be easy and fast to offload to a thread pool. If we can make it really easy to switch from one mode to the other, then most of the really hairy problems go away.

Re: Zero-cost futures in Rust

#197

Earlier quoted context omitted.

Well, they're two different points: closures in rust do not inherently have to heap allocate. But that also doesn't mean that they can _not_ be heap allocated either. And in this example, it's not even really the closures that allocate: it's still one allocation, regardless of the number of closures.

No. they are not two different points. You are artificially restricting the argument, and saying that some parts are a different question by introducing this new idea of "inherent nature" of a closure in rust : Some humans have legs, some do not. Does it mean that having legs is not an "inherent" part of the human experience? So to go back to the argument, we are trying to compare using a coroutine base approach vs u…

To use your analogy, I feel like you're saying that only humans that have legs are human. I'm saying that they're all human.

This analogy is weird.

Furthermore, because closures aren't inherently boxed, there might not even be a stack frame to begin with. Closures are syntax sugar for a struct + a trait implementation on that struct, and said call is then very inline-able.

This is also where I'm getting at with the single invocation thing: with these futures, all of these closures are going to be inlined into one big state machine, which is then itself eventually put on the heap. But that heap allocation has nothing to do with the closure, and more to do with the future wanting to not tie its data down to a specific stack frame.

Re: Zero-cost futures in Rust

#198

Earlier quoted context omitted.

> no sane way to intermix them. My understanding is, the idea is to put the blocking stuff in a threadpool with https://github.com/alexcrichton/futures-rs/tree/master/futur...

Right, there may be a lot of back and forth marshaling between using thread pools and not depending on whether the library you're using is futures based or not. Maybe you use one library that is futures-based and one that isn't. Maybe the library you use is mostly non-blocking except for one use of sleep() or another esotorically blocking call. It's just annoying and prone to error. Most people may not even be aware…

That's true. But caring about the details is the bread and butter of the kinds of programs that Rust is targetted at. If you can get away with the reduced performance, abstracting away those details is a totally reasonable choice. Rust is not and never can be a programming language for all programmers, and that's super okay.

Re: Zero-cost futures in Rust

#199

Earlier quoted context omitted.

C++ programmer here; re 3: the C++ coroutine proposals (there are multiple) are completely orthogonal to futures. The closest things in the standard to these rust futures, is of course std::future, which currently is very limited as it even lacks chaining and composition. The Concurrency TR (which eventually will be added to the standard, but sadly not for C++17) does provide these features (and more); multiple imple…

Thanks your answer clarifies a lot. So my question was , as a mechanism to implement async operation how does C++ coroutine compares to this rust library. From my understanding the C++ committee is pushing for the introduction of coroutine specifically because any library base approach would have the limitation you mentioned. Is that a correct ? You seems familiar with the C++ committee, do you know a good way to tra…

Coroutines would still run on top of std::future, it would be Just syntactic sugar to avoid callback hell via then chaining. In same case this might save some allocation as the callback would be a plain pointer to the control block, but that's about it.

I'm not part of the committee nor I attend meetings, but I follow the papers and the public online discussions.

Re: Zero-cost futures in Rust

#200

Earlier quoted context omitted.

Thanks your answer clarifies a lot. So my question was , as a mechanism to implement async operation how does C++ coroutine compares to this rust library. From my understanding the C++ committee is pushing for the introduction of coroutine specifically because any library base approach would have the limitation you mentioned. Is that a correct ? You seems familiar with the C++ committee, do you know a good way to tra…

Coroutines would still run on top of std::future, it would be Just syntactic sugar to avoid callback hell via then chaining. In same case this might save some allocation as the callback would be a plain pointer to the control block, but that's about it. I'm not part of the committee nor I attend meetings, but I follow the papers and the public online discussions.

From the last Gor paper, coroutine don't need to run on top of the std::future class. The type traits required allows for more computational patters (like generators, agent/actor, full coroutines) etc...
Post reply on HN