Live data from Hacker News

Async and Await in Rust: a full proposal

boats.gitlab.io

31–40 of 196 posts

Re: Async and Await in Rust: a full proposal

#31
post #24

As an embedded system dev, I'm wondering if these async features can be implemented on bare-metal (or without runtime)? Maybe I'm dumb and it might be a wild thought but it would be great if I could easily integrate async language features with hardware interrupts.

Pretty sure you need at least an operating system and memory allocation

Re: Async and Await in Rust: a full proposal

#32
Why does it have to be either one? Why not the possibility of choosing the implementation you want to solve the problem? A language where you could easily run whatever you want would have my vote. Not having it shoved down my throat (I’m looking at you JS). While it’s possible to build most of it yourself you should have the possibility to choose.

Re: Async and Await in Rust: a full proposal

#33
post #24

As an embedded system dev, I'm wondering if these async features can be implemented on bare-metal (or without runtime)? Maybe I'm dumb and it might be a wild thought but it would be great if I could easily integrate async language features with hardware interrupts.

Pretty sure you need at least an operating system and memory allocation

If I’m reading the proposal correctly, it’ll be possible and even straightforward because the standard library only provides the interface. You’ll be able to swap implementions by replacing the package with whatever fulfills the interface requirements.

Re: Async and Await in Rust: a full proposal

#34
post #5

I'm waiting for the day when 'async' will be the default function type and 'await' will be the default type of function call. If anywhere down the callstack a function needs to await something it has to become an async function. And this needs to be done to the whole callstack recursively. So over time more and more functions of every codebase turn into async functions.

One thing I like about Go is that there is no dichotomy between sync and async. Every function call presents a sync interface, but under the hood all I/O is async. I really miss this in Python, where every library has an async twin, usually maintained by someone unafiliated with the sync library.

Re: Async and Await in Rust: a full proposal

#35
I just finished reading the proposal and I’m super impressed and even excited. I really appreciate the commitment to not leaking implementation details into the standard library (i.e. exposing only the interface). This is fantastic for both embedded and (operating) system applications. Nice work everyone.

Re: Async and Await in Rust: a full proposal

#36
post #15
post #5

I'm waiting for the day when 'async' will be the default function type and 'await' will be the default type of function call. If anywhere down the callstack a function needs to await something it has to become an async function. And this needs to be done to the whole callstack recursively. So over time more and more functions of every codebase turn into async functions.

That model is called green threads. Continuation passing style means passing along your continuation to your callee, and is the implementation of the async model. But normal calls do pass their continuation: the return address, pushed on the stack, is the continuation function, and the stack itself is the scope, and together they are a closure. Make the stack a first class value that can be switched, and you get to c…

Green threads is very different from CPS actually both from an implementation and semantics point of view. In a CPS model the continuation is first class and is available at every single call point. In practice this would require heap allocating every single function frame, which is expensive and and a huge problem for interoperability (a smart compiler can turn it back to a traditional stack if the continuation is only used in traditional ways)

With the normall call/return model, the implicit continuation in a normal call stack can only be accessed via return. Green threads do allow accessing the continuation at specific yield points (although most green thread implementations do not expose it to the user) but because the yield point are much fewer than every single call, a whole stack can be allocated and used in one go. There aren't in fact many issues with interoperability as foregin functions or even os calls can be accommodated on this stack.

Async is a tradeoff, basically the programmer is responsible of marking functions that are to be CPS transformed and that need their stack frame reified. This way no full stack is needed nor there are the performance and interoperability issues of full CPS. You end up with the blue/red functions issue though.

Re: Async and Await in Rust: a full proposal

#37
post #23

Earlier quoted context omitted.

Having made "async" the default, you've just returned to regular threading, which is what we should have stuck with all along. The thread model is actually pretty useful, the pitfalls are well understood, and the tooling very mature.

Threading sucks. It's a situation where you have some external process (the operating system) deciding when different pieces of work should be woken up, with no way of feeding this back (so it just bases it on relatively naive schedulers). In practice, most of your threads are in one form of wait loop or another and you've just got polling both inside the threads and with the scheduler. Have a look at Erlang if you w…

Why would kernel threads be polling in practice? Won't most be waiting on locks, file descriptors, timers, etc?

Re: Async and Await in Rust: a full proposal

#38
post #5

I'm waiting for the day when 'async' will be the default function type and 'await' will be the default type of function call. If anywhere down the callstack a function needs to await something it has to become an async function. And this needs to be done to the whole callstack recursively. So over time more and more functions of every codebase turn into async functions.

Rust worked this way earlier in its development. The keyword as others mention is “green threads”. It moved away from this because this model has some overheads, and not every application is a socket server. Languages with this feature include Go, Haskell and Erlang.

And also the ABI compatibility for C interop is harder without a "classic" stack.

Re: Async and Await in Rust: a full proposal

#39
post #23

Earlier quoted context omitted.

Having made "async" the default, you've just returned to regular threading, which is what we should have stuck with all along. The thread model is actually pretty useful, the pitfalls are well understood, and the tooling very mature.

Threading sucks. It's a situation where you have some external process (the operating system) deciding when different pieces of work should be woken up, with no way of feeding this back (so it just bases it on relatively naive schedulers). In practice, most of your threads are in one form of wait loop or another and you've just got polling both inside the threads and with the scheduler. Have a look at Erlang if you w…

To pick some nits and generally elaborate, Erlang's VM also has a scheduler; it's not the presence or lack of a scheduler, it's how efficient it is and what guarantees it allows the programmer to make about their system. For example, OS schedulers are typically pre-emptive, which means your OS thread can get interrupted anywhere. On the otherhand, Go's scheduler (I'm using Go because I'm more familiar with it than with Erlang) only allows context switching at well-defined points in your program. Further, operating system threads have more overhead than in Go (presumably also Erlang) because they're fixed stack size (yes, I know this isn't true for all OSes).

Re: Async and Await in Rust: a full proposal

#40
post #24

As an embedded system dev, I'm wondering if these async features can be implemented on bare-metal (or without runtime)? Maybe I'm dumb and it might be a wild thought but it would be great if I could easily integrate async language features with hardware interrupts.

I'm not familiar with the way rust is going, but in general Async can be implemented purely a compile time by turning an async function into a set of functions tail calling each other or a switch statement. The stack frame need to go somewhere, but with allocator support this does not need to be exclusively handled by the runtime.
Post reply on HN