Live data from Hacker News

Zero-cost futures in Rust

aturon.github.io

21–30 of 348 posts

Re: Zero-cost futures in Rust

#21
post #15

So will this become the official part of the language / standard library?

That, if it happens, is still fairly far in the future. This isn't the only work on this space in Rust (see https://medium.com/@carllerche/announcing-tokio-df6bb4ddb34 for example, which also uses this library), so it's still in an early phase. Once everyone has actually used things and found it satisfactory, then such things can be discussed.

Re: Zero-cost futures in Rust

#22
post #8

Earlier quoted context omitted.

> 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 ? Similar in principle, but the implementation is different. Tasks in C# are more of an OO style instead of a FP style where they turn into an enum (sum type, if you want to get theoretical). > 2 - no allocation : , does'nt the lambda closure need to be allocated somewhere ? No, not…

Yes , i only have a simple understanding of rust memory model . So what happened when/if the future escapes/outlives the current stack/context ?

This is handled by the borrow checker, the same as anything else that might hold references to stack data - you get a compiler error and then can decide how to resolve the conflict, either by extending the lifetime of the referent (perhaps by boxing, or creating it earlier in the call stack), or by shrinking the lifetime of the future.

Re: Zero-cost futures in Rust

#23
post #8

Earlier quoted context omitted.

> 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 ? Similar in principle, but the implementation is different. Tasks in C# are more of an OO style instead of a FP style where they turn into an enum (sum type, if you want to get theoretical). > 2 - no allocation : , does'nt the lambda closure need to be allocated somewhere ? No, not…

Yes , i only have a simple understanding of rust memory model . So what happened when/if the future escapes/outlives the current stack/context ?

From the post

  > There are essentially no imposed synchronization costs; if you want
  > to associate data that lives on your event loop and access it in a
  > single-threaded way from futures, we give you the tools to do so.

Re: Zero-cost futures in Rust

#24
post #8

Earlier quoted context omitted.

> 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 ? Similar in principle, but the implementation is different. Tasks in C# are more of an OO style instead of a FP style where they turn into an enum (sum type, if you want to get theoretical). > 2 - no allocation : , does'nt the lambda closure need to be allocated somewhere ? No, not…

Yes , i only have a simple understanding of rust memory model . So what happened when/if the future escapes/outlives the current stack/context ?

It's an error if that would be unsafe, or else it compiles fine: the future compiles down to an enum/struct that stores everything inline and it can be returned/move up the stack/stored in global memory the same way that aggregate values returned without allocation (etc.) in C or C++.

Re: Zero-cost futures in Rust

#25
This is huge.

This allows one to express concurrency in a natural way not prone to the typical errors of problems of this nature, with no runtime overhead, while competing with C in terms of the constraints of the runtime.

Big kudos to Aaron Turon and Alex Crichton. You guys knocked it out of the park.

Re: Zero-cost futures in Rust

#26
post #8

Earlier quoted context omitted.

> 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 ? Similar in principle, but the implementation is different. Tasks in C# are more of an OO style instead of a FP style where they turn into an enum (sum type, if you want to get theoretical). > 2 - no allocation : , does'nt the lambda closure need to be allocated somewhere ? No, not…

Yes , i only have a simple understanding of rust memory model . So what happened when/if the future escapes/outlives the current stack/context ?

To be clear, the issue here isn't so much stack vs heap, as much as how many heap allocations are happening.

In practice, you build up a really big combined future on the stack, which has all of the space needed for any state in its state machine, and then when the future is fired off (in a task -- one per connection), that entire thing is moved into the heap in one shot. Thus, generally, you do one big allocation up front per connection -- exactly the same as you'd do when writing state machines by hand.

The follow up posts will go into much more detail on this point :)

Re: Zero-cost futures in Rust

#27
I dabbled with rust in the past and was really fascinated with it, but haven't played around lately. One thing caught my eye in the post:

    fn get_row(id: i32) -> impl Future;
That return type looks odd to me. What does it mean to return an "impl", and is that a new feature in rust, or just something advanced that I missed in my exploration before?

Re: Zero-cost futures in Rust

#28
post #8

Earlier quoted context omitted.

> 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 ? Similar in principle, but the implementation is different. Tasks in C# are more of an OO style instead of a FP style where they turn into an enum (sum type, if you want to get theoretical). > 2 - no allocation : , does'nt the lambda closure need to be allocated somewhere ? No, not…

Yes , i only have a simple understanding of rust memory model . So what happened when/if the future escapes/outlives the current stack/context ?

Compile error if it's holding on to any borrowed data on the stack - however, borrowing is only the default, if you move from a capture your closure will contain that value instead of reference to the value, and if you have "move" in front of your closure, all the captures are contained in the closure, so by boxing or by using -> impl Fn(...) you can safely return it.

If you need to hold onto data accessed from multiple locations, you'd need to use Rc instead of keeping that data on the stack, which is closer to GC'd languages (and pretty similar to Swift, IIUC, except Rust is more explicit).

Re: Zero-cost futures in Rust

#29

I dabbled with rust in the past and was really fascinated with it, but haven't played around lately. One thing caught my eye in the post: fn get_row(id: i32) -> impl Future ; That return type looks odd to me. What does it mean to return an "impl", and is that a new feature in rust, or just something advanced that I missed in my exploration before?

That is new syntax which has been accepted as a language change, but has not actually landed in the compiler yet. It was shown this way because it's much easier to understand, but is the same thing as it would be in the real code.

https://github.com/rust-lang/rfcs/blob/master/text/1522-cons... is an explanation of the feature in detail, but it boils down to "I will return you some kind of thing that implements the Future trait, but I'm not telling you exactly what it is."

Re: Zero-cost futures in Rust

#30

I dabbled with rust in the past and was really fascinated with it, but haven't played around lately. One thing caught my eye in the post: fn get_row(id: i32) -> impl Future ; That return type looks odd to me. What does it mean to return an "impl", and is that a new feature in rust, or just something advanced that I missed in my exploration before?

It's a new feature (hopefully to be merged this week). Here are the gory details:

https://github.com/rust-lang/rfcs/blob/master/text/1522-cons...

Post reply on HN